如何在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)

funcoperator.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')

最新更新