在使用 Python 装饰器时,需要注意以下几点:
装饰器的语法:装饰器是一个函数,它接受一个函数作为参数,并返回一个新的函数。装饰器的语法使用 @ 符号,将装饰器函数放在被装饰函数的定义之前。
装饰器的执行顺序:如果有多个装饰器,它们的执行顺序是从下往上执行,而函数的执行顺序是从上往下执行。
装饰器的参数:如果装饰器需要接受参数,可以在装饰器函数中定义参数,并在返回的新函数中使用这些参数。
装饰器的作用域:装饰器只能在当前模块中使用,如果需要在其他模块中使用,需要将装饰器导入到其他模块中。
装饰器的副作用:装饰器可能会对被装饰函数的行为产生副作用,例如修改被装饰函数的参数或返回值。因此,在使用装饰器时需要注意这些副作用可能会对程序的正确性产生影响。
from functools import wraps是用来干嘛的?
@wraps 是Python中的一个装饰器,它的作用是将被修饰函数的属性复制到修饰后的函数中。具体来说,它可以解决两个问题:
函数被装饰后,函数名和注释会变成装饰器的名字和注释。使用 @wraps 装饰器可以保留原来的函数名和文档字符串。
装饰后的函数会丢失一些属性,比如 __name __ 、__doc__等。使用 @wraps 装饰器可以继承原函数的这些属性。这样可以方便程序员的调试和帮助文档的生成。
例如:
from functools import wraps
def my_decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
"""wrapper docstring"""
print("Calling decorated function")
return func(*args, **kwargs)
return wrapper
@my_decorator
def example():
"""example docstring"""
print("Called example function")
print(example.__name__) # 输出 'example',而不是 'wrapper'
print(example.__doc__) # 输出 'example docstring',而不是 'wrapper docstring'
可以看到,使用 @wraps 装饰器后,装饰后的函数的名称和文档字符串都被正确地传递了下来。
不是面试根本用不到这块知识,感谢 wyhl 的耐心讲解