如何在Python中扩展第三方类的类型定义?
Python补第三方类类型提示的实用方法
Python确实没有TypeScript那种声明合并的功能,没法直接把原类定义和.pyi文件的部分定义合并,但有几个不用重写全部内容的办法来给nVersion补充类型提示:
方案1:临时用typing.cast标注
在用到nVersion的地方,用cast明确告诉类型检查器它的类型,不用改原类或加额外文件:
from typing import cast header = CBlockHeader() n_version = cast(int, header.nVersion) # 之后用n_version时,类型检查器会识别它是int类型
优点是简单快速,缺点是每个使用点都得手动加,不够省心。
方案2:子类继承或猴子补丁
子类方式
创建一个带类型注解的子类,完全继承原类的功能,只补充nVersion的类型:
from typing import override class TypedCBlockHeader(CBlockHeader): nVersion: int @override def __init__(self, nVersion: int = 2, hashPrevBlock=b'\x00'*32, hashMerkleRoot=b'\x00'*32, nTime=0, nBits=0, nNonce=0): super().__init__(nVersion, hashPrevBlock, hashMerkleRoot, nTime, nBits, nNonce) # 之后用TypedCBlockHeader代替原类就行 header = TypedCBlockHeader()
猴子补丁方式
直接给原类添加类型注解,只对类型检查器生效,不影响运行逻辑:
CBlockHeader.nVersion: int # 一行代码搞定全局类型提示
优点是一次标注全局生效,缺点是猴子补丁可能影响全局状态,子类继承时要注意。
方案3:写最小化的.pyi文件
不用完全重写原类的所有细节,只列出属性类型和方法的结构,用...(省略号)代替具体默认值:
# CBlockHeader.pyi from typing import bytes class CBlockHeader: nVersion: int hashPrevBlock: bytes hashMerkleRoot: bytes nTime: int nBits: int nNonce: int def __init__(self, nVersion: int = ..., hashPrevBlock: bytes = ..., hashMerkleRoot: bytes = ..., nTime: int = ..., nBits: int = ..., nNonce: int = ...) -> None: ...
这样类型检查器既能识别nVersion的类型,也能知道其他属性和方法的存在,工作量比完全重写小很多。
方案4:局部忽略+变量标注
如果只是少数地方用到,直接给变量加类型注解,或者用pyright的忽略注释关掉未知成员类型的报错:
header = CBlockHeader() # 直接给变量标注类型 n_version: int = header.nVersion # 或者临时关掉报错 # pyright: reportUnknownMemberType=false reveal_type(header.nVersion)
优点是灵活,只处理需要的地方,缺点是要逐个处理使用点。
内容的提问来源于stack exchange,提问作者M.K. Safi
相关产品推荐
相关产品推荐

