python 装饰器构造优酷视频登录程序

发布时间:2018-04-01 20:36:52编辑:admin阅读(5399)

    功能:

    1.用户3次登录,全部失败后,返回菜单

    2.用户必须登录才可以看电影

    3.用户注册,注册普通用户和VIP用户

    4.已经存在的用户,不允许重复注册

    4.VIP用户可以看所有电影,普通用户不能看后缀有VIP的电影

    5.可以随时返回主菜单


    完整代码如下:

    #!/usr/bin/env python
    # coding: utf-8
    __author__ = 'www.py3study.com'
    
    import time,os,sys
    '''
    本脚本运行会自动创建用户列表文件user_list.txt
    看电影函数watch_movie 用了装饰器
    用户必须登录才能看电影
    '''
    
    #用户登录状态
    user_status = {'username':'游客','status':False,'level':'无'}
    
    #文件名
    file_name = 'user_list.txt'
    
    def file_exists(*args,**kwargs):
        '''
        # 判断用户列表文件是否存在
        :return: True 存在 False 不存在
        '''
        # 判断文件是否存在
        if os.path.exists(file_name):
            return True
        else:
            with open(file_name, encoding='utf-8', mode='w') as mk:
                mk.write('xiao    123    VIP')
                return False
    
    
    def registered_username(username):
        '''
        #判断注册用户名是否可用
        :param username: 用户名
        :return: True 可用(用户不存在) False 不可用(用户已存在)
        '''
        if username == '':
            return '用户名不能为空'
        # 纯用户名列表,不包含密码
        user_list = []
        with open(file_name, encoding='utf-8') as f1:
            for i in f1:
                # 去空格,以空格切割,转换为列表
                li = i.strip().split()  # [张三,123]
                # 将用户名追加到列表中
                user_list.append(li[0])
            # 判断用户名是否存在列表中
            if username in user_list:
                # 返回False
                return False
            else:
                return True
    
    
    def write_file(username,password,level):
        '''
        #写入用户列表文件
        :param username: 用户名
        :param password: 密码
        :return: True 写入成功 False 写入失败
        '''
        if username == '' or password == '':
            return '用户名或者密码不能为空!'
        with open(file_name, encoding='utf-8', mode='a') as f2:
            f2.write('\n{}    {}    {}'.format(username, password,level))
            return True
    
    
    def username_password(username,password):
        '''
        #判断用户名和密码是否匹配
        :param username: 用户名
        :param password: 密码
        :return: True 匹配成功 False 匹配失败
        '''
        if username == '' or password == '':
            return '用户名或者密码不能为空!'
        with open(file_name, encoding='utf-8', mode='r') as f3:
            for i in f3:
                # print(i)
                # 去空格,以空格切割,转换为列表
                li = i.strip().split()  # [张三,123]
                # 判断用户名和密码是否匹配
                if username == li[0] and password == li[1]:
                    #result = True
                    result = {'msg':True,'level':li[2]}
                    # 当找到匹配时,跳出循环
                    break
                else:
                    #result = False
                    result = {'msg': False, 'level': li[2]}
            # 当整个用户列表遍历完成之后,再return
            return result
    
    
    def register(*args,**kwargs):
        '''
        注册逻辑
        :return:
        '''
        while True:
            print('请选择用户类型\n1.普通用户\n2.VIP用户\n')
            user_type = input('请输入编号: ').strip()
            if user_type == '1' or user_type == '2':
                break
            else:
                print("\033[41;1m输入错误,请重新输入!\033[0m")
    
        while True:
            username = input('请输入注册的用户名,或输入q返回菜单:').strip()
            if username == '':
                print("\033[41;1m用户名为空,请重新输入!\033[0m")
            elif username.upper() == 'Q':
                break
            else:
                # 执行判断用户名函数
                result = registered_username(username)
                if result:
                    password = input('请输入您的注册的密码:').strip()
                    # 判断密码
                    if password == '':
                        print("\033[41;1m密码为空,请重新输入!\033[0m")
                    else:
                        # 执行写入用户列表文件函数
                        if user_type == '1':
                            level = '普通'
                        else:
                            level = 'VIP'
                        result = write_file(username, password,level)
                        if result:
                            print('注册成功!,您的用户名为: {}\n倒计时2秒返回菜单!'.format(username))
                            time.sleep(2)
                            login_menu()
                        else:
                            print("\033[41;1m注册失败!请重试!\033[0m")
                else:
                    print("\033[41;1m用户名已经存在,请重新输入!\033[0m")
    
    
    def login(count=0,max=3):
        '''
        登录逻辑
        :param count: 初始失败次数
        :param max: 最大失败次数
        :return:
        '''
        global user_status
    
        while count < max:
            count += 1
            username = input('请输入用户名:').strip()
            if username == '':
                print("\033[41;1m用户名不能为空!\033[0m")
            password = input('请输入密码:').strip()
            if password == '':
                print("\033[41;1m密码不能为空!\033[0m")
            # 执行验证用户名和密码函数
            result = username_password(username,password)
            if result['msg']:
                print('登陆成功\n倒计时1秒返回菜单!')
                user_status['username'] = username
                user_status['status'] = True
                user_status['level'] = result['level']
                time.sleep(1)
                user_menu(username)
                #rihan()
                break
            else:
                print("\033[41;1m用户名或密码错误,还剩余{}次机会!\033[0m".format(max - count))
    
    
    def check_login(func): #检查登陆的装饰器
        def inner(*args,**kwargs):
            if user_status['status']:
                r = func(*args,**kwargs)
                return r
            else:
                print("\033[41;1m请先登录!\033[0m")
                login_menu()
        return inner
    
    def view_bar(): #显示进度条
        for i in range(100):
            k = i + 1
            #这一行的数字3用来控制宽度,同时改为4,宽度就变窄
            #\033[32m>\033[0m 进度条是> 可以改成其他的. \033[32m绿色 \033[0m 终端默认颜色
            str = '\033[32m✈\033[0m' * (i // 4) + ' ' * ((100 - k) // 4)
            sys.stdout.write('\r' + str + '[%s%%]' % (i + 1))
            sys.stdout.flush()
            time.sleep(0.03)
    
    @check_login
    def watch_movie(name): #看电影函数
        if name == '':
            return '电影名不能为空'
        if name.endswith('VIP'):
            if user_status['level'] == 'VIP':
                print('正在播放电影 {}'.format(name))
                view_bar()
                print('\n')
                return
            else:
                print("\033[41;1m此影片只对VIP会员开放!\033[0m")
        else:
            print('正在播放影片 {}'.format(name))
            view_bar()
            print('\n')
            return
    
    
    def user_menu(username='游客'): #用户电影列表
        while True:
            # 打印菜单
            movie_list = ['首杀','黑暗塔','鲨滩','环太平洋 VIP','变形金刚5:最后的骑士 VIP','生化危机:终章 VIP','返回菜单']
            info = '当前登陆用户:{} 状态: {} 等级:{}'.format(user_status['username'],user_status['status'],user_status['level'])
            print(info.rjust(15))
            print('༺ཌ༈电影列表༈ད༻'.center(23, '♚'))
            for i in range(len(movie_list)):
                print('{}\t{}'.format(i + 1, movie_list[i]))
            print(''.center(23, '❆'))
            number = input('请选择序号: ').strip()
            # 判断输入的是否是数字
            if number.isdigit():
                number = int(number)
                #判断是否选择退出
                if number == len(movie_list):
                    break
                #用户选择电影
                if number > 0 and number < len(movie_list):
                    name = movie_list[number - 1]
                    #执行看电影函数
                    watch_movie(name)
                else:
                    print("\033[41;1m输入错误,请重新输入!\033[0m")
            else:
                print("\033[41;1m输入错误,请重新输入!\033[0m")
    
    
    def login_menu():
        '''
        # 用户菜单
        '''
        # 判断文件是否存在,不存在创建文件
        file_exists()
        # 循环
        while True:
            # 打印菜单
            menu = ['注册', '登录/切换','电影','退出']
            #菜单函数名对照表
            menu_func = ['register', 'login', 'user_menu', 'exit']
            print('꧁优酷视频꧂'.center(15, '❀'))
            print('\n')
            info = '当前登陆用户:{}'.format(user_status['username'])
            print(info.rjust(15))
            print(''.center(18, '☪'))
            for i in range(len(menu)):
                print('{}\t{}'.format(i + 1, menu[i]))
            print(''.center(20, '☬'))
            number = input('请选择序号: ').strip()
            #判断输入的是否是数字
            if number.isdigit():
                number = int(number)
                if number > 0 and number <= len(menu):
                    #获取函数名,使用eval将字符串变成有效的表达式,执行函数
                    eval(menu_func[number - 1])()
            else:
                print("\033[41;1m输入错误,请重新输入!\033[0m")
    
    
    # 执行菜单
    login_menu()

    输出,稍微装饰了一下,执行效果如下:

    youku2.gif

关键字