Skip to main content
 首页 » 编程设计

python之如果你从另一个脚本中导入一个装饰过的 python 函数会发生什么

2025年05月04日21lonelyxmas

我正在查看带有装饰器的 Flask 后端中的一个函数,并考虑将其导入另一个脚本并以不同的方式对其进行装饰。有谁知道当你导入它时会发生什么,装饰器是否与它一起使用?

我看过this但它更多地讨论了同一脚本中发生的事情。

请您参考如下方法:

不,导入装饰函数不会移除装饰器。

导入从源模块的全局命名空间中检索当前对象,并且装饰函数导致装饰器返回值存储在全局命名空间中。

导入模块主要是modulename = sys.modules['modulename'](对于import modulename)和objectname = sys.modules['modulename'].objectname 分配(对于 from modulename import objectname,在任何一种情况下首先确保 sys.modules 有加载所需的模块),模块中的全局变量与模块对象的属性相同。装饰只是 functionname = decorator(functionobject) 的语法糖。

如果需要给导入的函数添加新的装饰器,调用装饰器即可:

from somemodule import somedecoratedfunction 
 
newname_or_originalname = decorator(somedecoratedfunction) 

如果导入的装饰函数不适合在新层中再次装饰,或者您想访问原始的未装饰函数,请查看对象是否具有 __wrapped__ 属性:

from somemodule import somedecoratedfunction 
 
unwrapped_function = somedecoratedfunction.__wrapped__ 

写得很好的装饰器使用 @functools.wraps() decorator ,它将该属性设置为指向原始:

>>> from functools import wraps 
>>> def demodecorator(f): 
...     @wraps(f) 
...     def wrapper(*args, **kwargs): 
...         print("Decorated!") 
...         return f(*args, **kwargs) 
...     return wrapper 
... 
>>> @demodecorator 
... def foo(name): 
...     print(f"Hello, {name or 'World'}!") 
... 
>>> foo('cardamom') 
Decorated! 
Hello, cardamom! 
>>> foo.__wrapped__('cardamom') 
Hello, cardamom!