网站首页 > 博客文章 正文
Python 是动态类型语言, 只在运行时做 Duck Typing 检查.
- 利: 灵活, 方便
- 弊: 代码混乱, 缺少规范
标准自带两类接口支持: abc 和 typing.Protocol, 有他们协助给天马行空的程序员套上枷锁, Python 的大工程才可以"上道"
abc
abc 就是 Abstract Base Class, 虚基类. 跟 Java, C++ 中的虚基类是一个意思, 可以对派生类提供实例化时的动态检查, 确保虚拟接口 (abstractmethod) 都有实现
import abc
class Base(abc.ABC):
@abstractmethod
def foo(self, s: str):
"""abc interface demo
"""
class Invalid(Base):
pass
class Child(Base):
def foo(self):
pass
c = Child()
assert isinstance(c, Base)
# TypeError: Can't instantiate abstract class Invalid with abstract methods foo
i = Invalid()
也提供了非侵入式的虚基类关联方法
from abc import ABC
class MyABC(ABC):
pass
MyABC.register(tuple)
assert issubclass(tuple, MyABC)
assert isinstance((), MyABC)
- 检查时机: 在运行中当派生类实例化时
- 检查范围: 只确保 abstractmethod 是否在派生类中有相同函数名实现, 并不检查实现的参数和返回值是否相同. 只看名字不比签名
- 代码影响: 侵入式, 需要继承. 也有手工非侵入式方案
typing.Protocol
structure subtyping (static duck-typing)
import typing
class Countable(typing.Protocol):
def count(self, who: str) -> int:
"""support count
"""
class Counter:
def count(self, who: str) -> int:
return 0
c = Counter()
def f(c: Countable):
c.count("bill")
- 检查时机: 静态类型检查接口使用方, 例如 mypy
- 检查范围: 确保实现类按照签名实现了接口的全部函数
- 代码影响: 非侵入式, 不需要继承
比较
abc 类似 c++ 中的虚基类, typing.Protocol 则好比 c++ 中的 concept.
当然, Python 是动态语言, 在 typing.runtime_checkable 和 abc.abstractmethod 加成后, typing.Protocol 动静两相宜
import typing
@typing.runtime_checkable
class Countable(typing.Protocol):
@abc.abstractmethod
def count(self, who: str) -> int:
"""support count
"""
class Counter:
def count(self, who: str) -> int:
return 0
assert issubclass(Counter, Countable)
c = Counter()
assert isinstance(c, Countable)
def f(c: Countable):
assert isinstance(c, Countable)
print(c.count("bill"))
f(c)
class InvalidCounter(Countable):
def c(self):
pass
# TypeError: Can't instantiate abstract class InvalidCounter with abstract methods count
i = InvalidCounter()
上面这个终极解决方案兼有两者的优点:
- 静态类型检查时会确保是否在派生类中有相同签名的实现
- 动态运行时, 会检查是否同名函数存在
- 代码影响: 自动非侵入式, 不需要继承, 也无需手工注册
猜你喜欢
- 2024-10-12 C++核心准则T.24:用标签类或特征区分只有语义不同的概念
- 2024-10-12 用苹果发布会方式打开C++20(苹果在哪开发布会)
- 2024-10-12 C++核心准则T.25:避免互补性约束(规矩是一种约束,一种准则)
- 2024-10-12 C++核心准则T.21:为概念定义一套完整的操作
- 2024-10-12 C++核心准则T.5:结合使用泛型和面向对象技术应该增强效果
- 2024-10-12 C++经典书籍(c++相关书籍)
- 2024-10-12 C++一行代码实现任意系统函数Hook
- 2024-10-12 C++核心准则T.11:只要可能就使用标准概念
- 2024-10-12 C++核心准则T.48:如果不能用概念,用enable_if
- 2024-10-12 C++核心准则T.13:简单、单类型参数概念使用缩略记法更好
你 发表评论:
欢迎- 最近发表
-
- 给3D Slicer添加Python第三方插件库
- Python自动化——pytest常用插件详解
- Pycharm下安装MicroPython Tools插件(ESP32开发板)
- IntelliJ IDEA 2025.1.3 发布(idea 2020)
- IDEA+Continue插件+DeepSeek:开发者效率飙升的「三体组合」!
- Cursor:提升Python开发效率的必备IDE及插件安装指南
- 日本旅行时想借厕所、买香烟怎么办?便利商店里能解决大问题!
- 11天!日本史上最长黄金周来了!旅游万金句总结!
- 北川景子&DAIGO缘定1.11 召开记者会宣布结婚
- PIKO‘PPAP’ 洗脑歌登上美国告示牌
- 标签列表
-
- ifneq (61)
- messagesource (56)
- aspose.pdf破解版 (56)
- promise.race (63)
- 2019cad序列号和密钥激活码 (62)
- window.performance (66)
- qt删除文件夹 (72)
- mysqlcaching_sha2_password (64)
- ubuntu升级gcc (58)
- nacos启动失败 (64)
- ssh-add (70)
- jwt漏洞 (58)
- macos14下载 (58)
- yarnnode (62)
- abstractqueuedsynchronizer (64)
- source~/.bashrc没有那个文件或目录 (65)
- springboot整合activiti工作流 (70)
- jmeter插件下载 (61)
- 抓包分析 (60)
- idea创建mavenweb项目 (65)
- vue回到顶部 (57)
- qcombobox样式表 (68)
- vue数组concat (56)
- tomcatundertow (58)
- pastemac (61)
本文暂时没有评论,来添加一个吧(●'◡'●)