Duck-typing 用户定义 类
Duck-typing user-defined classes
所以 Python 的核心语言和内置函数使用了大量鸭子类型。但是对于我们自己的代码,假设我想用一种处理对象 "certain types" 的方法创建自己的 class,使用 duck typing 是否更惯用:
class MerkleTree:
def method(self, document):
try:
hash_ = document.sha256_hash()
except AttributeError:
raise TypeError()
do_smth_with_hash(hash_)
还是只使用普通类型检查更符合习惯:
class MerkleTree:
def method(self, document):
if isinstance(document, SHA256Hashable):
raise TypeError()
hash_ = document.sha256_hash()
do_smth_with_hash(hash_)
从纯类型的角度来看,MerkleTree.method
将接受 any 类型的参数; Python没有办法限制。
从鸭子打字的角度来看,您保证
def method(self, document):
hash_ = document.sha256_hash()
do_smth_with_hash(hash_)
只要 document.sha256_hash
是可调用的,其 return 值适合 do_smth_with_hash
使用,但 method
不执行任何强制。您的文档说明了调用 method
的先决条件,但是否满足该先决条件取决于调用者,违反它的任何后果都是调用者的问题,而不是 method
的问题。
您可以提供类型提示(使用 Protocol
class),以 mypy
等静态类型检查工具可以验证的方式更正式地记录此先决条件。
class ShaHashable(typing.Protocol):
def sha256_hash(self):
pass
class MerkleTree:
def method(self, document: ShaHashable):
hash_ = document.sha256_hash()
do_smth_with_hash(hash_)
通常情况下,您不会仅仅为了引发一种不同类型而捕获一个异常。用户通过阅读文档了解到,如果 document
没有合适的方法,method
可能会引发 AttributeError
,并且 mypy
可以帮助捕获该错误,而不必 运行代码。
小型甚至中型项目最好使用 duck typing,大型项目最好使用 PEP484+mypy。
EG:
python3 -m mypy --disallow-untyped-calls ${files}
并且:
def pad(number: int) -> str:
顺便说一句,如果您已经有一个没有 PEP484 类型注释的大型项目,您可以使用类似 MonkeyType 的东西来添加它们。
所以 Python 的核心语言和内置函数使用了大量鸭子类型。但是对于我们自己的代码,假设我想用一种处理对象 "certain types" 的方法创建自己的 class,使用 duck typing 是否更惯用:
class MerkleTree:
def method(self, document):
try:
hash_ = document.sha256_hash()
except AttributeError:
raise TypeError()
do_smth_with_hash(hash_)
还是只使用普通类型检查更符合习惯:
class MerkleTree:
def method(self, document):
if isinstance(document, SHA256Hashable):
raise TypeError()
hash_ = document.sha256_hash()
do_smth_with_hash(hash_)
从纯类型的角度来看,MerkleTree.method
将接受 any 类型的参数; Python没有办法限制。
从鸭子打字的角度来看,您保证
def method(self, document):
hash_ = document.sha256_hash()
do_smth_with_hash(hash_)
只要 document.sha256_hash
是可调用的,其 return 值适合 do_smth_with_hash
使用,但 method
不执行任何强制。您的文档说明了调用 method
的先决条件,但是否满足该先决条件取决于调用者,违反它的任何后果都是调用者的问题,而不是 method
的问题。
您可以提供类型提示(使用 Protocol
class),以 mypy
等静态类型检查工具可以验证的方式更正式地记录此先决条件。
class ShaHashable(typing.Protocol):
def sha256_hash(self):
pass
class MerkleTree:
def method(self, document: ShaHashable):
hash_ = document.sha256_hash()
do_smth_with_hash(hash_)
通常情况下,您不会仅仅为了引发一种不同类型而捕获一个异常。用户通过阅读文档了解到,如果 document
没有合适的方法,method
可能会引发 AttributeError
,并且 mypy
可以帮助捕获该错误,而不必 运行代码。
小型甚至中型项目最好使用 duck typing,大型项目最好使用 PEP484+mypy。
EG:
python3 -m mypy --disallow-untyped-calls ${files}
并且:
def pad(number: int) -> str:
顺便说一句,如果您已经有一个没有 PEP484 类型注释的大型项目,您可以使用类似 MonkeyType 的东西来添加它们。