python 2.07 装饰器进阶试题

装饰器进阶 测试

作业

  1. 请为以下所有函数编写一个装饰器,添加上装饰器后可以实现:执行func时,先执行func函数内部代码,再输出 "after"

    def func(a1):
        return a1 + "傻叉"
    
    def base(a1,a2):
        return a1 + a2 + '傻缺'
    
    
    def foo(a1,a2,a3,a4):
        return a1 + a2 + a3 + a4 + '傻蛋'
    
    #
    import functools
    def outer(funcs):
        functools.wraps(funcs)
        def wrapper(*xargs,**kwargs):
            res = funcs(*xargs,**kwargs)
            print('after')
            return res
        return wrapper
    
    @outer
    def func(a1):
        return a1 + "傻叉"
    
    print(func("1231"))
    
    
  2. 请为以下所有函数编写一个装饰器,添加上装饰器后可以实现:将被装饰的函数执行5次,讲每次执行函数的结果按照顺序放到列表中,最终返回列表。

    import random
    import functools
    # 请为以下所有函数编写一个装饰器,添加上装饰器后可以实现:将被装饰的函数执行5次,讲每次执行函数的结果按照顺序放到列表中,最终返回列表。
    
    def outer(funcs):
        functools.wraps(funcs)
    
        def wrapper(*xargs,**kwargs):
            res_list = []
            for i in range(5):
                res = funcs(*xargs,**kwargs)
                res_list.append(res)
            return  res_list
        return wrapper
    
    
    @outer
    def func():
        return random.randint(1,4)
    
    result = func() # 内部自动执行5次,并将每次执行的结果追加到列表最终返回给result
    print(result)
    
    第二 生成式
    
    def outer(funcs):
        functools.wraps(funcs)
        def wrapper(*xargs,**kwargs):
            return  [funcs(*xargs,**kwargs) for i in range(5) ]
        return wrapper
    
    @outer
    def func():
        return random.randint(1,4)
    
    result = func() # 内部自动执行5次,并将每次执行的结果追加到列表最终返回给result
    print(result)
    
  3. 请为以下函数编写一个装饰器,添加上装饰器后可以实现: 检查文件所在路径(文件件)是否存在,如果不存在自动创建文件夹(保证写入文件不报错)。

    def write_user_info(path):
        file_obj = open(path, mode='w', encoding='utf-8')
        file_obj.write("武沛齐")
        file_obj.close()
    
    write_user_info('/usr/bin/xxx/xxx.png')
    #########
    # 请为以下函数编写一个装饰器,添加上装饰器后可以实现: 检查文件所在路径(文件件)是否存在,如果不存在自动创建文件夹(保证写入文件不报错)。
    import functools
    import os.path
    
    
    def outter(func):
        functools.wraps(func)
    
        def wrapper(*xargs, **kwargs):
            if not os.path.exists(os.path.dirname(*xargs)):
                os.makedirs(os.path.dirname(*xargs))
            res = func(*xargs, **kwargs)
            return res
    
        return wrapper
    
    
    @outter
    def write_user_info(path):
        file_obj = open(path, mode='w', encoding='utf-8')
        file_obj.write("123231")
        file_obj.close()
    
    
    write_user_info(r'C:\Python001\day01\filaaaaa\123.txt')
    
    
  4. 分析代码写结果:

    def get_data():
        scores = []
    
        def inner(val):
            scores.append(val)
            print(scores)
    
        return inner
    
    
    func = get_data()
    
    func(10)
    func(20)
    func(30)
    #
    10
    10,20
    10,20,30
    
  5. 看代码写结果

    name = "武沛齐"
    
    
    def foo():
        print(name)
    
    
    def func():
        name = "root"
        foo()
    
    
    func()
    
    # root
    
    
  6. 看代码写结果

    name = "武沛齐"
    
    
    def func():
        name = "root"
    
        def foo():
            print(name)
    
        foo()
    
    
    func()
    #root
    
    
  7. 看代码写结果

    def func(val):
        def inner(a1, a2):
            return a1 + a2 + val
    
        return inner
    
    func(val) = a1 +a2 +val
    
    data_list = []
    
    for i in range(10):
        data_list.append(  func(i)   )
    
    print(data_list)
    列表里面是func(0,1,..9),又因为func函数的返回值是inner函数。所以
    列表的元素是inner函数。
    [inner函数,inner函数,inner函数,inner函数,]
    
  8. 看代码写结果

    def func(val):
        def inner(a1, a2):
            return a1 + a2 + val
    
        return inner
    
    
    data_list = []
    
    for i in range(10):
        data_list.append(func(i))  # append 插入是顺序插入 0.。。9
    
    v1 = data_list[0](11,22)
    v2 = data_list[2](33,11)
    
    print(v1)  # 列表的元素加括号代表执行函数,11,22 传参 ,元素的索引值等于i的值,   11 +22 +0  =33
    print(v2)     33+11+2=46
    
    
    
  9. 编写函数(函数执行时间用time.sleep(n)代表)

def index(num):
    for i in range(num):
        print('run %s'%num)

index(5)

#
def index(num):
    time.sleep(num)
    print('run %s秒' % num)
index(5)
  1. 编写装饰器,为函数添加统计时间的功能
import time
from functools import wraps

def outter(func):
    @wraps(func)
    def wrapper(*xargs,**kwargs):
        'help'
        start_time= time.time()
        res= func(*xargs,**kwargs)
        stop_time= time.time()
        print('run times is  %s S'%(stop_time-start_time))
        return res
    return wrapper


@outter
def index(num):
    for i in range(num):
        print('run %s'%num)
        time.sleep(3)

index(5)
  1. 编写装饰器 为函数加上认证的功能
import time
from functools import wraps

def login(func):
    def wrapper(*xargs,**kwargs):
        imp_name = input('type you name: ').strip('')
        imp_paswwd  = input('type you password: ').strip('')
        if imp_name == '123' and imp_paswwd =='123':
            print('welcome,loging sucess')
            res= func(*xargs,**kwargs)
            return res
        else:
            print('name or password error')

    return wrapper

def outter(func):
    @wraps(func)
    def wrapper(*xargs,**kwargs):
        'help'
        start_time= time.time()
        res= func(*xargs,**kwargs)
        stop_time= time.time()
        print('run times is  %s S'%(stop_time-start_time))
        return res
    return wrapper

@login
@outter
def index(num):
    for i in range(num):
        print('run %s'%num)
        time.sleep(3)
index(5)
  1. 编写装饰器,为多个函数加上认证的功能(用户的账号密码来源于文件),要求登录成功一次,
后续的函数都无需再输入用户和密码。
注意从文件中读出字符串形式的字典,可以用eval({'name':'zhangshan','password':'123'})转成字典格式
# 思路  1、把文件中用户名和密码传到字典中去
#      2、登录函数 把输入的用户名和密码和 字典中的用户和密码 进行对比
#      3、登录函数内 把对比后的结果传回全局变量中去。

#      4、登录装饰器 把装饰器函数加到其他函数头部
#      5、在登录装饰器内部,校验全局变量是否有用户登录状态,如果有则调用原始函数
#      6、如果状态是空,调用登录函数

import time

with open('db.txt','r',encoding='utf-8') as f:

    user_dict = eval(f.read())


log_user = {'name':None}
# 全局变量分为可变类型和不可变类型 (变量的值更改后,值所在的内存地址会不会变,不会变成为可变类型,会变称为不可变类型)
# globals 定义全局变量在函数内修改,如果是可变类型不需要加globals 不可变类型的话就需要加声明


def login():
    while True:
        imp_name = input('type name :').strip('')
        imp_password = input('type password :').strip('')
        if imp_name == user_dict['name'] and imp_password == user_dict['password']:
            print('loging ssuccessful!')
            log_user['name'] = imp_name
            # print(log_user.get('name'))
            break
        else:
            print('user or pass error')

def outter(func):
    def wrapper(*xargs,**kwargs):
        if log_user['name']:
            res = func(*xargs,**kwargs)
            return res
        else:
            login()

    return wrapper


@outter
def index1(x):
    for i in range(x):
        print('index1')


@outter
def index2(x):
    for i in range(x):
        print('index2')


@outter
def index3(x):
    for i in range(x):
        print('index3')

index1(1)
time.sleep(2)
index2(1)
index3(1)
  1. 编写装饰器,为多个函数添加上认证功能,要求登录成功一次,在超时时间是5秒 ,无需重复登录。超过了超时时间,则必须重新登录
import time

with open('db.txt','r',encoding='utf-8') as f:

    user_dict = eval(f.read())


login_user = {'name':None}


def login():
    while True:
        imp_name = input('type name :').strip('')
        imp_password = input('type password :').strip('')
        if imp_name == user_dict['name'] and imp_password == user_dict['password']:
            print('loging ssuccessful!')
            old_time= time.time()
            global login_user
            login_user['name']=[imp_name,imp_password,old_time]
            
            break
        else:
            print('user or pass error')

def outter(func):
    def wrapper(*xargs,**kwargs):
        if login_user['name']:
            new_time = time.time()
       
            if (new_time-login_user['name'][2]) <= 5:
     
                res = func(*xargs,**kwargs)
                return res
            else:
                login()
                
        else:

            login()

    return wrapper


@outter
def index1(x):
    for i in range(x):
        print('index1')


@outter
def index2(x):
    print('index2')



index1(1)

time.sleep(6)

index2(1)
总结 4、5 两题 在第一个函数的认证功能执行成功后,应该去执行当前装饰的函数,不应该跳过,
              超时时间过了,再去执行函数时,应该重新认证后,再去执行函数
# 更新版本
import time

with open('db.txt', 'r', encoding='utf-8') as f:
    user_dict = eval(f.read())

login_user = {'name': None}


def login():
    while True:
        imp_name = input('type name :').strip('')
        imp_password = input('type password :').strip('')
        if imp_name == user_dict['name'] and imp_password == user_dict['password']:
            print('loging ssuccessful!')
            old_time = time.time()
            global login_user
            login_user['name'] = [imp_name, imp_password, old_time]

            break
        else:
            print('user or pass error')


def outter(func):
    def wrapper(*xargs, **kwargs):
        if login_user['name']:
            new_time = time.time()

            if (new_time - login_user['name'][2]) <= 5:

                res = func(*xargs, **kwargs)
                return res
            else:
                login()
                res = func(*xargs, **kwargs)
                return res

        else:

            login()
            res = func(*xargs, **kwargs)
            return res

    return wrapper


@outter
def index1(x):
    for i in range(x):
        print('index1')


@outter
def index2(x):
    print('index2')


index1(1)

time.sleep(6)

index2(1)
  1. ATM项目中使用 函数对象 + 字典的方式做了一个格式化的输出
现在需要在文件开头声明一个空的字典,然后在每个函数前加上装饰器,完成自动添加到字典的操作
第一种方式
func_dict= {}

x= 0
def outter(func):
    global x

    func_dict[x]=func
    x += 1
    def wrapper(*xargs,**kwargs):

        res = func(*xargs,**kwargs)
        return res
    return wrapper

@outter
def index1():pass
@outter
def index2():pass
@outter
def index3():pass
@outter
def index4():pass
@outter
def index5():pass
print(func_dict)
第二种方式
func_dict = {}
def outter(func):
    func_dict[func.__name__]=func
    def wrapper(*xargs, **kwargs):
        res = func(*xargs, **kwargs)
        return res

    return wrapper
@outter
def index1(): pass


@outter
def index2(): pass


@outter
def index3(): pass


@outter
def index4(): pass


@outter
def index5(): pass


for i in func_dict:
    print('%s   %s '%(i,func_dict[i]))
  1. 编写日志装饰器,实现功能: 一旦执行函数f1 ,则消息 20xx-xx-xx 00:00:00 f1 run 写到日志文件中去
import  time
time_date = time.strftime('%Y-%m-%d %X')

def outter(func):
    def wrapper(*xargs,**kwargs):
        res = func(*xargs,**kwargs)
        with open('log.txt','a',encoding='utf-8') as f:
            f.write('%s %s run \n'%(time_date,func.__name__))

        return res

    return wrapper


@outter
def log():

    print('log .......')

log()
posted @ 2022-01-13 16:27  mmszxc  阅读(61)  评论(0)    收藏  举报