python装饰器分析_分析掌握python装饰器(二)

看完(一)后,想必已经对装饰器有了一个基本的概念。在(二)中,我将会对装饰器的一些高级用法做一点研究记录。

1、装饰器带其他参数

接着上面的例子,我们希望并不是每个人都有权限去使用这个计算函数,只有特定的人才可以。

def checktype(personname=None):

def decorate(func):

def wrapper(*args,**kwargs):

count = 0

if personname == 'ghy':

str = []

for n in args:

if not isinstance(n,(int,float)):

log= '{}的类型无法计算'.format(n)

str.append(log)

count += 1

if count == 0:

return func(*args,**kwargs)

else:

print(str)

else:

print('{}, you are limited'.format(personname))

return wrapper

return decorate

@checktype('test')

def calfunc(*numbers,sign=None):

if sign is None:

return 'please input a sign'

if hasattr(case['+'], '__call__'):

add=case['+']

return print(add(*numbers))

#调用

calfunc('a','b',sign='+') #输出 test you are limited

2、自定义装饰器属性

有时候我们会想通过为装饰器定义一些属性,来修改其中的参数

如上个例子所示,我们想通过属性来修改personname的值

from functools import wraps,partial

#将函数属性附加到包装函数上

#使用partial函数

#from functools import partial

#partial 函数的作用就是

#把一个函数的某些参数给固定住(也就是设置默认值),返回一个新的函数,调用这个新函数会更简单。

#第一个参数为原函数。

def add_attr(obj,func=None):

if func is None:

return partial(add_attr,obj)

setattr(obj,func.__name__,func)

return func

#装饰器

def checktype(personname=None):

def decorate(func):

#保留原函数的一些元数据 比如 函数名 不加 calfunc.__name__输出 wrapper

@wraps(func)

def wrapper(*args,**kwargs):

count = 0

if personname == 'ghy':

str = []

for n in args:

if not isinstance(n,(int,float)):

log= '{}的类型无法计算'.format(n)

str.append(log)

count += 1

if count == 0:

return func(*args,**kwargs)

else:

print(str)

else:

print('{}, you are limited'.format(personname))

@add_attr(wrapper) #相当于 add_attr(wrapper)()=>add_attr(wrapper,sef_modifypersonname)

def sef_modifypersonname(newname):

nonlocal personname # 如果没有这个,下面一句是在当前作用域内又创建了一个personame

personname = newname

return wrapper

return decorate

@checktype('test')

def calfunc(*numbers,sign=None):

if sign is None:

return 'please input a sign'

if hasattr(case['+'], '__call__'):

add=case['+']

return print(add(*numbers))

calfunc(1,2,sign='+') #输出 test you are limited

calfunc.sef_modifypersonname('ghy')

calfunc(1,2,sign='+') #输出 3

#装饰器解包,调用__wrapped__ 不进入装饰器包装函数

calfunc.sef_modifypersonname('test')

calfunc.__wrapped__(1,2,sign='+') #输出 3

上面一个比较重要的稍微难以理解的点就是@add_attr(wrapper),但其实你只要明白了

装饰器是在代码解释的时候就已经调用执行了

也就是说我们的装饰器处的代码,我们可以心里自动给它默认为

sef_modifypersonname=add_attr(wrapper)(sef_modifypersonname)

还有一个即 @wraps(func)注释已经写的很清楚了,保留原函数的元数据。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值