car*_*mom 4 python decorator python-3.x
我正在查看烧瓶后端中带有装饰器的函数,并考虑将其导入另一个脚本并以不同的方式装饰它。有谁知道当你导入它时会发生什么,无论装饰器是否伴随它?
我看过这个,但它更多地讨论了同一脚本中发生的事情。
不,导入装饰函数不会删除装饰器。
导入从源模块的全局命名空间中检索当前对象,装饰函数会导致装饰器返回值存储在全局命名空间中。
导入模块主要modulename = sys.modules['modulename']是(for import modulename) 和objectname = sys.modules['modulename'].objectname赋值(for 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()装饰器,它将该属性设置为指向原始属性:
>>> 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包含对原始未修饰函数的引用,否则您无法从导入的模块访问它。
暴露原文的一个例子:
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)
| 归档时间: | 
 | 
| 查看次数: | 2974 次 | 
| 最近记录: |