如何从`from * import variable`语句中提取interface?
如何获取
from * import导入的接口 嘿,这个问题我之前在项目里也碰到过,来给你一步步拆解清楚~首先得明确:我们说的「接口」通常指抽象基类(ABC)、PEP 484定义的Protocol,或者模块里暴露的类/函数型公共接口。下面分两种场景来说明方法:
场景1:已经显式导入了某个变量(比如from module import MyInterface)
如果已经知道要找的接口名字,直接用inspect模块就能轻松获取它的方法或属性:
1. 处理抽象基类(ABC)
假设你的接口是用abc.ABC和@abstractmethod定义的,要提取它的抽象方法(也就是必须实现的接口方法):
import inspect from my_module import MyInterface # 获取所有抽象方法 abstract_methods = inspect.getmembers(MyInterface, predicate=inspect.isabstractmethod) # 输出方法名列表 print([method_name for method_name, _ in abstract_methods]) # 如果要获取所有方法(包括非抽象的) all_class_methods = inspect.getmembers(MyInterface, predicate=lambda x: inspect.isfunction(x) or inspect.ismethod(x))
2. 处理Protocol协议
如果是PEP 484的Protocol类型接口,同样用inspect提取成员:
import inspect from my_module import MyProtocol # 获取Protocol定义的所有公共成员(过滤掉特殊属性) protocol_members = [ (name, member) for name, member in inspect.getmembers(MyProtocol) if not name.startswith('__') ] print(protocol_members)
场景2:用from module import *导入了所有名字
这种情况因为命名空间被污染,你可能不知道哪些是目标接口,得先筛选出候选对象:
from my_module import * import inspect import abc from typing import Protocol # 先获取当前命名空间里的所有非内置名字 imported_names = [name for name in dir() if not name.startswith('__')] # 遍历筛选接口类型 for name in imported_names: obj = locals()[name] # 判断是否是抽象基类 if isinstance(obj, type) and issubclass(obj, abc.ABC): print(f"找到抽象接口:{name}") # 提取它的抽象方法 methods = inspect.getmembers(obj, predicate=inspect.isabstractmethod) print(f"接口必须实现的方法:{[m[0] for m in methods]}") # 判断是否是Protocol协议 elif isinstance(obj, type) and issubclass(obj, Protocol): print(f"找到Protocol接口:{name}") members = inspect.getmembers(obj) print(f"协议成员:{[m[0] for m in members if not m[0].startswith('__')]}")
小提醒
其实非常不推荐用from module import *这种导入方式——它会污染当前命名空间,导致名字冲突,也很难追踪变量来源。最好还是显式导入你需要的接口(比如from my_module import MyInterface, MyProtocol),这样操作起来更清晰,也不容易出错。
内容的提问来源于stack exchange,提问作者Falieson
相关产品推荐
相关产品推荐

