python - Python 装饰器导入时间
问题描述
我正在一个全局集中注册我的一些函数:
# registry.py
import functools
schedule_registry = set()
def register_scheduler(func):
@functools.wraps(func)
def func_wrapper():
print(f"adding {func.__name__}")
schedule_registry.add(func)
return func
return func_wrapper
@register_scheduler
def foo():
print("running foo")
现在,我希望schedule_registry
在导入时填写(并打印“添加...”),但令我惊讶的是:
In [1]: import registry
In [2]:
没有打印任何内容。
问题是,如果我将装饰器更改为以下内容:
def register_scheduler():
def func_wrapper(func):
print(f"adding {func.__name__}")
schedule_registry.add(func)
return func
return func_wrapper
@register_scheduler()
def foo():
print("running foo")
我得到了我的期望:
In [1]: import registry
adding foo
解决方案
这和 没有任何关系wraps
。
你还没有理解装饰器是如何工作的。外部函数在导入时被调用,并返回替换被修饰函数的内部函数。然后调用内部函数代替原始函数,因此需要采用其原始参数 - not func
。如果您希望在导入时发生任何事情,则需要进入外部函数。
def register_scheduler(func):
print(f"adding {func.__name__}")
schedule_registry.add(func)
@functools.wraps(func)
def func_wrapper(*args, **kwargs):
print(f"at call time")
return func(*args, **kwargs)
return func_wrapper
请注意,您的两个示例都根本不起作用;第一个不调用修饰函数,第二个在导入时调用内部函数,没有任何东西代替被修饰的函数。
推荐阅读
- javascript - Angular2+:在多个 div 中切换元素
- java - ArrayList 中存储多种数据类型时,ArrayList.get() 的性能会受到影响吗?
- gis - 行程时间可达区域
- scala - scala spark - saveAsTextFile - 文件名
- javascript - 如何使用 php 和 mysql 验证单选按钮?
- java - 使用命令行 gradle 从测试源执行 main()
- elasticsearch - Elasticsearch 重新索引错误 - 客户端请求超时
- hyperledger-fabric - 创建新通道、新组织并与每个组织分开发送锚点对等交易
- apache - htaccess 在子目录中无法正常工作
- lua - 'nil' 作为 Lua 表中的一个元素?