Python中如何在接口实现类的实例上调用任意指定的接口方法
关于Python抽象接口方法动态调用的问题
背景定义
首先定义了继承自ABC的抽象接口:
from abc import ABC, abstractmethod class SomeInterface(ABC): @abstractmethod def foo(self): """要求所有实现类都要实现的方法""" @abstractmethod def bar(self): """要求所有实现类都要实现的方法"""
以及该接口的两个实现类:
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")
需求与尝试
需求是实现一个通用函数,接收接口的抽象方法作为参数,在函数内部创建所有接口实现类的实例,运行实例上对应传入参数的方法。
第一次的错误写法如下:
from typing import Callable def run_any_interface_method(func: Callable): a = A() a.func() b = B() b.func() run_any_interface_method(SomeInterface.foo)
该写法无法运行,因为尝试访问实例的func属性,而func是传入的参数变量,不是实例实际的属性名。
第二次尝试调整为直接将实例作为self传入抽象方法:
def run_any_interface_method(func: Callable): a = A() func(a) b = B() func(b) run_any_interface_method(SomeInterface.foo)
该写法运行不会报错,但调用的是父类的抽象空方法,不会执行子类的实现逻辑,没有预期输出。
可行解决方案
方案1:使用operator.methodcaller(提问者采用的方案)
通过methodcaller根据方法名生成可调用对象,传入实例时会自动调用实例上对应名称的绑定方法,正确触发子类实现:
from operator import methodcaller from typing import Callable 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)
运行后输出符合预期:
A does foo like this B does foo like this
方案2:使用getattr动态获取实例方法
不需要导入额外模块,直接通过方法名从实例中获取绑定方法再调用,效果和方案1一致:
from typing import Callable def run_any_interface_method(func: Callable): method_name = func.__name__ a = A() getattr(a, method_name)() b = B() getattr(b, method_name)() run_any_interface_method(SomeInterface.foo)
扩展优化:自动获取所有接口实现类
如果实现类数量较多,可以通过__subclasses__方法自动获取SomeInterface的所有直接子类,不需要手动逐个实例化:
from operator import methodcaller from typing import Callable def run_any_interface_method(func: Callable): caller = methodcaller(func.__name__) # 遍历所有接口实现类 for impl_cls in SomeInterface.__subclasses__(): instance = impl_cls() caller(instance)
内容的提问来源于stack exchange,提问作者Tomass Wilson
相关产品推荐
相关产品推荐

