我正在尝试将动态导入的模块中的附加功能注册到单分派功能。
main.py
from importlib import import_module
from functools import singledispatch
@singledispatch
def handle(a):
return 'default'
def import_something():
other_module = import_module('dynimp')
handle_result = handle(1)
assert handle_result == 'int', f'Error: {handle_result}'
if __name__ == '__main__':
import_something()
dynimp.py
from main import handle
@handle.register(int)
def handle_int(a):
return 'int'
中的断言import_something
失败,我得到'default'
,而不是'int'
。
我进一步调查了一下。函数对象在导入时以某种方式被复制dynimp
。如果我在 之后设置断点other_module = import_module('dynimp')
,other_module.handle != handle
而 whileother_module.registry
显示handle_int
为已注册,handle.registry
则不会。
一个有效的解决方案是在 中有一个register
函数dynimp.py
,然后传递它handle
:
def do_register(handle_fn):
handle_fn.register(int, handle_int)
然后添加other_module.do_register(handle)
的import_something
功能。
我的问题是:当我们导入一个装饰函数时会发生什么,为什么这不起作用?
发生这种情况是因为import main
创建了主文件的新实例。确认这一点的简单方法是以下代码:
>>> sys.modules['main'] == sys.modules['__main__']
False
一种解决方案是更改from main import handle
为from __main__ import handle
. (请注意,这依赖于main.py
作为启动程序的文件的文件。)另一种解决方法是sys.modules['main'] = sys.modules['__main__']
在导入dynimp
.
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句