Python 在动态导入的模块中注册singledispatch函数

Python 在动态导入的模块中注册singledispatch函数,python,python-3.x,Python,Python 3.x,我试图将动态导入的模块中的附加函数注册到singledispatch函数中 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

我试图将动态导入的模块中的附加函数注册到singledispatch函数中

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()
from main import handle

@handle.register(int)
def handle_int(a):
    return 'int'
dynimp.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()
from main import handle

@handle.register(int)
def handle_int(a):
    return 'int'
import\u something
中的断言失败,我得到的是
'default'
,而不是
'int'

我做了进一步的调查。在
dynimp
中导入时,函数对象以某种方式被复制。如果我在
other_module=import_module('dynimp')
之后设置断点,
other_module.handle!=句柄
其他模块。注册表
显示已注册的
句柄
,而
句柄。注册表
不显示

一个有效的解决方案是在
dynimp.py
中有一个
寄存器
函数,并传递它
句柄

def do_register(handle_fn):
    handle_fn.register(int, handle_int)
然后添加
其他模块。在
import\u something
函数中注册(句柄)


我的问题是:导入修饰函数时会发生什么,为什么不起作用?

这是因为
import main
会创建主文件的新实例。确认这一点的简单方法是以下代码:

>>> sys.modules['main'] == sys.modules['__main__']
False

一种解决方案是将
从主导入句柄
更改为
从主导入句柄
。(请注意,这取决于启动程序的文件是
main.py
文件。)另一种解决方法是在导入
dynimp
之前设置
sys.modules['main']=sys.modules['''umain']
,因为
import main
会创建主文件的新实例。确认这一点的简单方法是以下代码:

>>> sys.modules['main'] == sys.modules['__main__']
False
一种解决方案是将
从主导入句柄
更改为
从主导入句柄
。(请注意,这取决于启动程序的文件是
main.py
文件。)另一种解决方法是在导入
dynimp
之前设置
sys.modules['main']=sys.modules['''main']