0%

functools模块魔术方法

partial

就是把某个函数的某个参数固定,从而创建出一个新的函数;

  1. 示例:
1
2
3
4
5
6
from functools import partial
def add(x:int, y:int):
return x+y
# 这里创造了一个新的函数add2,只接受一个整型参数,然后将这个参数统一加上2
add2 = partial(add, y=2)
add2(3) # 这里将会输出5
  1. 源码
1
2
3
4
5
6
7
8
9
def partial(func, *args, **keywords):
def newfunc(*fargs, **fkeywords):
newkeywords = keywords.copy()
newkeywords.update(fkeywords)
return func(*args, *fargs, **newkeywords)
newfunc.func = func
newfunc.args = args
newfunc.keywords = keywords
return newfunc

update_wrapper

从 被修饰的函数(wrapped) 中取出一些属性值来,赋值给 修饰器函数(wrapper)

  1. 源码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
WRAPPER_ASSIGNMENTS = ('__module__', '__name__', '__qualname__', '__doc__','__annotations__')
WRAPPER_UPDATES = ('__dict__',)
def update_wrapper(wrapper,
wrapped,
assigned = WRAPPER_ASSIGNMENTS,
updated = WRAPPER_UPDATES):
for attr in assigned:
try:
value = getattr(wrapped, attr)
except AttributeError:
pass
else:
setattr(wrapper, attr, value)
for attr in updated:
getattr(wrapper, attr).update(getattr(wrapped, attr, {}))
wrapper.__wrapped__ = wrapped
return wrapper
  1. 自定义装饰器1
1
2
3
4
5
6
7
8
9
10
11
12
def wrapper(f):
def wrapper_function(*args, **kwargs):
"""这个是修饰函数"""
return f(*args, **kwargs)
return wrapper_function

@wrapper
def wrapped():
"""这个是被修饰的函数"""
print('wrapped')
print(wrapped.__doc__) # 输出`这个是修饰函数`
print(wrapped.__name__) # 输出`wrapper_function`
  1. 自定义装饰器2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
from functools import 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():
"""这个是被修饰的函数"""
print('wrapped')
print(wrapped.__doc__) # 输出`这个是被修饰的函数`
print(wrapped.__name__) # 输出`wrapped`

wraps

一个修饰器版的update_wrapper函数,它的功能和update_wrapper是一模一样的;

  1. 源码
1
2
3
4
5
6
7
WRAPPER_ASSIGNMENTS = ('__module__', '__name__', '__qualname__', '__doc__','__annotations__')
WRAPPER_UPDATES = ('__dict__',)
def wraps(wrapped,
assigned = WRAPPER_ASSIGNMENTS,
updated = WRAPPER_UPDATES):
return partial(update_wrapper, wrapped=wrapped,
assigned=assigned, updated=updated)
  1. 自定义装饰器3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from functools import wraps
def wrapper(f):
@wraps(f)
def wrapper_function(*args, **kwargs):
"""这个是修饰函数"""
return f(*args, **kwargs)
return wrapper_function

@wrapper
def wrapped():
"""这个是被修饰的函数
"""
print('wrapped')
print(wrapped.__doc__) # 输出`这个是被修饰的函数`
print(wrapped.__name__) # 输出`wrapped