如何在 python 中的具体实例上调用任意接口方法?

How can I call an arbitrary interface method on a concrete instance in python?

假设我有一个带有几个抽象方法的接口

class SomeInterface(ABC):

    @abstractmethod
    def foo(self):
        """Does something i want all implementers to do"""

    @abstractmethod
    def bar(self):
        """Does something i want all implementers to do"""

还有几个实现

class A(SomeInterface):

    def foo(self):
        print("A does foo like this")

    def bar(self):
        print("A does bar like this")

class B(SomeInterface):

    def foo(self):
        print("B does foo like this")

    def bar(self):
        print("B does bar like this")

通过该设置,我处于这样一种情况,我希望有一个函数可以 运行 我在该接口的某些实现上指定的一些接口函数。因此,该函数可以将某种形式的 foo 或 bar 引用作为参数,然后 运行 它创建的 A 和 B 的某些实例。像这样:

def run_any_interface_method(func: Callable):
    a = A()
    a.func()
    
    b = B()
    b.func()
    
run_any_interface_method(SomeInterface.foo)

但这当然行不通。最好的解决方案应该是什么?我可能有许多可能的 SomeInterface 实现和许多接口函数。我考虑过这个解决方案:

def run_any_interface_method(func: Callable):
    a = A()
    func(a)
    
    b = B()
    func(b)
    
run_any_interface_method(SomeInterface.foo)

它传递实例,AB,作为参数self,但func在这种情况下仍然是未实现的抽象方法,所以它确实什么都没有(有趣的是,这样做时它不会抱怨)。我考虑过遍历方法的名称以找到正确的方法,但这似乎很笨拙。有没有更好的方法?

编辑 我采用的解决方案是:

from operator import methodcaller

def run_any_interface_method(func: Callable):
    func = methodcaller(func.__name__)
    a = A()
    func(a)

    b = B()
    func(b)

run_any_interface_method(SomeInterface.foo)

func成为operator.methodcaller的实例。

from operator import methodcaller


def run_any_interface_method(func):
    a = A()
    func(a)

    b = B()
    func(b)

# Run a.foo() and b.foo()
run_any_interace_method(methodcaller('foo'))

# Run a.bar() and b.bar()
run_any_interace_method(methodcaller('bar'))

您也可以将字符串作为参数,并在函数内构造 methodcaller 实例。

def run_any_interface_method(method_name):
    func = methodcaller(method_name)
    a = A()
    func(a)

    b = B()
    func(b)

# Run a.foo() and b.foo()
run_any_interace_method('foo')

# Run a.bar() and b.bar()
run_any_interace_method('bar')