首页 > 其他 > 详细

装饰器的一般用法

时间:2020-01-05 15:30:36      阅读:82      评论:0      收藏:0      [点我收藏+]

基本写法:

1 def log(func):
2     def wrapper(*args, **kw):
3         print(call %s(): % func.__name__)
4         return func(*args, **kw)
5     return wrapper

之后如果在函数上方@log一下就相当于添加了log的功能

@log
def now():
    print(2015-3-25)

 

具体的意思是:

now = log(now)

也就是说now的函数地址传给了log,log return了wrapper,此时now的函数地址变为了闭包函数wrapper。

额,所以,对于装饰器个人观点就是wrapper对函数进行了闭包处理。

 

经过对函数的调试,我发现当出现@log的时候,会出现加载函数的过程。也就是外层的函数wrapper在没有now()运行的时候也照样加载了一遍,也就是这样:

def log(func):
    print(加载中。。。。。。。)
    def wrapper(*args, **kw):
        print(call %s(): % func.__name__)     
        return func(*args, **kw)
    return wrapper

@log
def now():
    print(index)
print(f.__name__)
###############

加载中。。。。。。。
wrapper

 

所以这下都清楚了,@log就是一个now变为wrapper这样函数地址转移的过程,并且会运行wrapper函数外层的代码。

含参写法:

def one(file=txt):
    print(外层函数加载中。。。)
    def decorator(func):
        def wrapper(*args,**kw):
            print(出现了出现了,函数地址转移)
            return func(*args,**kw)
        return wrapper
    return decorator
@one(‘txt‘)
def f():
    print("完成了,f=one(‘txt‘)(f)")
f()
外层函数加载中。。。
出现了出现了,函数地址转移
完成了,f=one(txt)(f)

加了一层,但是不慌,原理还是那个原理。

f=one(‘txt‘)(f)

首先传参‘txt’,取到函数地址decorator,之后变为了f=decorator(f),是不是莫名的熟悉。

题目:编写装饰器,为多个函数加上认证的功能(用户的账号密码来源于文件),要求登录成功一次,后续的函数都无需再输入用户名和密码

db=db.txt
index={"name":None,"status":False}

def log(filetype=txt):
    def decorator(func):
        def wrapper(*args,**kw):
            if index["name"] and index["status"]:
                return func(*args,**kw)
            if filetype==txt:
                name=input(请输入姓名).strip()
                password=input(请输入密码).strip()


                with open(db,encoding=utf8) as f:
                    for line in f:
                        dic=eval(line.strip())
                        if name in dic[user] and password in dic[password]:
                            index[name]=name
                            index[status]=True
                            return func(*args,**kw)
                    else:
                        print("姓名或者密码输入错误")
            else:
                print(文件类型错误)
        return wrapper
    return decorator


@log(txt)
def f(a,b,c):
    res=a+b+c
    print(res)


@log()
def x():
    print("认证功能成功")

f(1,2,3)
x()

稍微写的有点多了,但看懂并写出这一题的话,装饰器的基本使用应该没问题了。对于装饰器多功能的使用以后再补充吧。




装饰器的一般用法

原文:https://www.cnblogs.com/chengdz/p/12152428.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!