partial、update_wrapper、wraps的使用
引用
from functools import wraps, update_wrapper, partial
1. partial
partial又叫偏函数。函数在执行的时候需要带上必要的参数,有些参数是执行之前就是可知的,这种情况下,一个函数有一个或者多个函数预先就能用上,以便函数能够更少的参数进行调用。
# 定义一个函数
def add(x, y):
return x + y
add1 = partial(add, y=3) # 这里创建了一个新的函数
print add1(4) # 7
print add(x=4, y=9) # 13
2. update_wrapper
update_wrapper这个函数的主要功能是负责copy原函数的一些属性,如moudle、name、doc、等,如果不加update_wrapper,那么被装饰器修饰的函数就会丢失其上面的一些属性信息
# 定义装饰器
def wrapper(f):
def wrapper_function(*args, **kwargs):
return f(*args, **kwargs)
update_wrapper(wrapper_function, f)
return wrapper_function
@wrapper
def wrapped():
pass
print(wrapped.__doc__) # 输出`这个是被修饰的函数`
print(wrapped.__name__) # 输出`wrapped`
# __doc__和__name__属性已经是wrapped函数中的,当然,update_wrapper函数也对__module__和__dict__等属性进行了更改和更新
3. wraps
被装饰器修饰后的函数会编程另外一个函数,为了不受影响,利用wraps来消除这样的副作用,使它能够保持原函数的属性。
# 定义装饰器
def wrapper(f):
@wraps(f)
def wrapper_function(*args, **kwargs):
return f(*args, **kwargs)
return wrapper_function
@wrapper
def wrapped():
pass
带参数的装饰器
来想想这个问题,难道@wraps不也是个装饰器吗?但是,它接收一个参数,就像任何普通的函数能做的那样。
那么,为什么我们不也那样做呢? 这是因为,当你使用@my_decorator语法时,你是在应用一个以单个函数作为参数的一个包裹函数。
记住,Python里每个东西都是一个对象,而且这包括函数!记住了这些,我们可以编写一下能返回一个包裹函数的函数。
在函数中嵌入装饰器
创建一个包裹函数,能让我们指定一个用于输出的日志文件。
from functools import wraps
def logit(logfile='out.log'):
def logging_decorator(func):
@wraps(func)
def wrapped_function(*args, **kwargs):
log_string = func.__name__ + " was called"
print(log_string)
# 打开logfile,并写入内容
with open(logfile, 'a') as opened_file:
# 现在将日志打到指定的logfile
opened_file.write(log_string + '\n')
return func(*args, **kwargs)
return wrapped_function
return logging_decorator
@logit()
def myfunc1():
pass
myfunc1()
# Output: myfunc1 was called
# 现在一个叫做 out.log 的文件出现了,里面的内容就是上面的字符串
@logit(logfile='func2.log')
def myfunc2():
pass
myfunc2()
# Output: myfunc2 was called
# 现在一个叫做 func2.log 的文件出现了,里面的内容就是上面的字符串
标签:__,wraps,partial,函数,update,wrapper,装饰,def
From: https://www.cnblogs.com/clearheart/p/17335853.html