2024-04-19 09:27:27 发布
网友
我正在查看一个flask后端中带有装饰器的函数,并考虑将其导入另一个脚本并以不同的方式装饰它。有人知道当你导入它时会发生什么吗,不管装饰师是否同意?你知道吗
我看过this,但它更多地讨论了在同一个脚本中发生的事情。你知道吗
不,导入修饰函数不会删除修饰器。你知道吗
导入从源模块的全局命名空间中检索当前对象,修饰函数会导致decorator返回值存储在全局命名空间中。你知道吗
对于modulename = sys.modules['modulename'](对于import modulename)和objectname = sys.modules['modulename'].objectname赋值(对于from modulename import objectname,在任何一种情况下,首先确保sys.modules加载了所需的模块之后),导入模块都是语法上的糖分,模块中的全局变量与模块对象上的属性是一样的。装饰只是functionname = decorator(functionobject)的语法糖。你知道吗
modulename = sys.modules['modulename']
import modulename
objectname = sys.modules['modulename'].objectname
from modulename import objectname
sys.modules
functionname = decorator(functionobject)
如果需要向导入的函数添加新的decorator,只需调用decorator:
from somemodule import somedecoratedfunction newname_or_originalname = decorator(somedecoratedfunction)
如果导入的修饰函数不适合在新层中再次修饰,或者您希望访问原始的未修饰函数,请查看对象是否具有__wrapped__属性:
__wrapped__
from somemodule import somedecoratedfunction unwrapped_function = somedecoratedfunction.__wrapped__
编写良好的decorators使用^{} 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!
修饰函数
@some_decorator def some_func(...): ...
相当于将函数应用于另一个对象:
def some_func(...): ... some_func = some_decorator(some_func)
导入模块时,您可以访问的只是当前绑定到some_func的对象,它是应用于原始函数的some_decorator的返回值。除非返回的东西some_decorator包含对原始未修饰函数的引用,否则您无法从导入的模块访问它。你知道吗
some_func
some_decorator
原作曝光示例:
def some_decorator(f): def _(*args, *kwargs): # Do some extra stuff, then call the original function # ... return f(*args, **kwargs) _.original = f return _ @some_decorator def some_func(...): ...
导入模块时,some_module.some_func引用修饰函数,但原始的未修饰函数可通过some_module.some_func.original使用,但仅可用,因为编写修饰器是为了使其可用。(正如Martijn Peters指出的,wraps装饰器为您做了这件事和其他一些好事,但是装饰器仍然需要使用wraps。)
some_module.some_func
some_module.some_func.original
wraps
不,导入修饰函数不会删除修饰器。你知道吗
导入从源模块的全局命名空间中检索当前对象,修饰函数会导致decorator返回值存储在全局命名空间中。你知道吗
对于
modulename = sys.modules['modulename']
(对于import modulename
)和objectname = sys.modules['modulename'].objectname
赋值(对于from modulename import objectname
,在任何一种情况下,首先确保sys.modules
加载了所需的模块之后),导入模块都是语法上的糖分,模块中的全局变量与模块对象上的属性是一样的。装饰只是functionname = decorator(functionobject)
的语法糖。你知道吗如果需要向导入的函数添加新的decorator,只需调用decorator:
如果导入的修饰函数不适合在新层中再次修饰,或者您希望访问原始的未修饰函数,请查看对象是否具有
__wrapped__
属性:编写良好的decorators使用^{} decorator ,它将该属性设置为指向原始属性:
修饰函数
相当于将函数应用于另一个对象:
导入模块时,您可以访问的只是当前绑定到
some_func
的对象,它是应用于原始函数的some_decorator
的返回值。除非返回的东西some_decorator
包含对原始未修饰函数的引用,否则您无法从导入的模块访问它。你知道吗原作曝光示例:
导入模块时,
some_module.some_func
引用修饰函数,但原始的未修饰函数可通过some_module.some_func.original
使用,但仅可用,因为编写修饰器是为了使其可用。(正如Martijn Peters指出的,wraps
装饰器为您做了这件事和其他一些好事,但是装饰器仍然需要使用wraps
。)相关问题 更多 >
编程相关推荐