假设我想为名为“MacroMethods”的模块中的每个类设置函数。所以我在'Fluent Python'中看到它后设置了singledispatch,如下所示:
@singledispatch
def addMethod(self, obj):
print(f'Wrong Object {str(obj)} supplied.')
return obj
...
@addMethod.register(MacroMethods.Wait)
def _(self, obj):
print('adding object wait')
obj.delay = self.waitSpin.value
obj.onFail = None
obj.onSuccess = None
return obj
期望的行为是 - 当类 'MacroMethods.Wait' 的实例作为参数给出时,singledispatch 运行具有该类类型的注册函数。
相反,它运行默认功能而不是注册功能。
>>> Wrong Object <MacroMethods.Wait object at 0x0936D1A8> supplied.
但是, type() 清楚地显示实例是类“MacroMethods.Wait”,并且 dict_keys 属性也包含它。
>>> dict_keys([<class 'object'>, ..., <class 'MacroMethods.Wait'>])
我怀疑我制作的所有自定义类都算作“对象”类型,并且没有在结果中运行所需的函数。
有什么办法可以解决这个问题?完整的代码在这里。
更新
我设法模仿singledispatch
的动作如下:
from functools import wraps
def state_deco(func_main):
"""
Decorator that mimics singledispatch for ease of interaction expansions.
"""
# assuming no args are needed for interaction functions.
func_main.dispatch_list = {} # collect decorated functions
@wraps(func_main)
def wrapper(target):
# dispatch target to destination interaction function.
nonlocal func_main
try:
# find and run callable for target
return func_main.dispatch_list[type(target)]()
except KeyError:
# If no matching case found, main decorated function will run instead.
func_main()
def register(target):
# A decorator that register decorated function to main decorated function.
def decorate(func_sub):
nonlocal func_main
func_main.dispatch_list[target] = func_sub
def register_wrapper(*args, **kwargs):
return func_sub(*args, **kwargs)
return register_wrapper
return decorate
wrapper.register = register
return wrapper
像这样使用:
@state_deco
def general():
return "A's reaction to undefined others."
@general.register(StateA)
def _():
return "A's reaction of another A"
@general.register(StateB)
def _():
return "A's reaction of B"
但仍然不是singledispatch
,所以我发现将其发布为答案可能不合适。