我可能在这里缺少明显的东西。我有一个简单的类层次结构,大致如下所示:
class Any:
def op2_additive_add(self, other: 'Any') -> 'Any':
raise NotImplementedError
def op2_multiplicative_multiply(self, other: 'Any') -> 'Any':
raise NotImplementedError
def op2_exponential_power(self, other: 'Any') -> 'Any':
raise NotImplementedError
# A dozen of similar methods not shown
class Rational(Any):
def op2_additive_add(self, other: 'Any') -> 'Rational':
pass # Implementation not shown
def op2_multiplicative_multiply(self, other: 'Any') -> 'Rational':
pass # Implementation not shown
def op2_exponential_power(self, other: 'Any') -> 'Rational':
pass # Implementation not shown
class Set(Any):
def op2_additive_add(self, other: 'Any') -> 'Set':
pass # Implementation not shown
def op2_multiplicative_multiply(self, other: 'Any') -> 'Set':
pass # Implementation not shown
def op2_exponential_power(self, other: 'Any') -> 'Set':
pass # Implementation not shown
# Half a dozen of similar derived types not shown.
我正在实现一个调度程序类,该调度程序类应在两个操作数上选择所请求的操作,而又不知道它们的类型,然后将对正确方法的引用传递给执行程序。大致像这样(下面的代码将不起作用):
def select_operator(selector) -> typing.Callable[[Any, Any], Any]:
if selector.such_and_such():
return Any.op2_additive_add
elif selector.so_and_so():
return Any.op2_exponential_power
# And so on
上面的代码将不起作用,因为尝试调用返回的未绑定方法将绕过动态调度;即select_operator(selector)(foo, bar)
将始终抛出NotImplementedError
。
到目前为止,我能想到的最好的解决方案大致是这样,而且还不很漂亮:
def select_operator(selector) -> str:
if selector.such_and_such():
return Any.op2_additive_add.__name__
elif selector.so_and_so():
return Any.op2_exponential_power.__name__
# And so on
method_name = select_operator(selector)
getattr(foo, method_name)(bar)
TL; DR:如何延迟动态分配过程,直到我引用了某个方法?
答案 0 :(得分:1)
也许这会更合适?
class Any:
def select_and_do_op(self, selector, other):
if selector.such_and_such():
return self.op2_additive_add.(other)
elif selector.so_and_so():
return self.op2_exponential_power(other)
...
foo.select_and_do_op(selector, bar)
更新
另一个解决方案:
def select_operator(selector):
if selector.such_and_such():
return lambda foo, bar: foo.op2_additive_add(bar)
elif selector.so_and_so():
return lambda foo, bar: foo.op2_exponential_power(bar)
...
operator = select_operator(selector)
result = operator(foo, bar)