参考纯虚方法

问题描述 投票:1回答:1

我可能遗漏了一些明显的东西。我有一个简单的类层次结构,看起来大致如下:

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:在我参考方法之前,如何延迟动态调度过程?

python polymorphism late-binding dynamic-dispatch
1个回答
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)

UPDATE

另一个解决方案:

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)
© www.soinside.com 2019 - 2024. All rights reserved.