Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/291.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Duck类型用户定义的类_Python_Typing_Duck Typing - Fatal编程技术网

Python Duck类型用户定义的类

Python Duck类型用户定义的类,python,typing,duck-typing,Python,Typing,Duck Typing,因此Python的核心语言和内置程序使用了大量duck类型。但是对于我们自己的代码,假设我想用处理“特定类型”对象的方法创建自己的类,那么使用duck类型是否更为惯用: classmerkletree: def方法(自我、文档): 尝试: hash_uu=document.sha256_hash() 除属性错误外: raise TypeError() 使用哈希(hash)进行排序 还是只使用普通类型检查更为惯用: classmerkletree: def方法(自我、文档): 如果存在(文档,S

因此Python的核心语言和内置程序使用了大量duck类型。但是对于我们自己的代码,假设我想用处理“特定类型”对象的方法创建自己的类,那么使用duck类型是否更为惯用:

classmerkletree:
def方法(自我、文档):
尝试:
hash_uu=document.sha256_hash()
除属性错误外:
raise TypeError()
使用哈希(hash)进行排序
还是只使用普通类型检查更为惯用:

classmerkletree:
def方法(自我、文档):
如果存在(文档,SHA256Hashable):
raise TypeError()
hash_uu=document.sha256_hash()
使用哈希(hash)进行排序

从纯类型的角度来看,
MerkleTree.method
将接受任何类型的参数;Python无法限制它

从鸭子打字的角度来看,你保证

def method(self, document):
    hash_ = document.sha256_hash()
    do_smth_with_hash(hash_)
只要
文档就可以使用。sha256\u hash
是一个可调用函数,其返回值适合
do\u smth\u with\u hash
使用,但
方法
不执行任何强制操作。您的文档说明了调用
方法的先决条件,但这取决于调用方是否满足该先决条件,违反该先决条件的任何后果都是调用方的问题,而不是
方法的问题

您可以提供一个类型提示(使用
协议
类),以一种静态类型检查工具(如
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_)

通常,您不会仅仅为了引发一个不同类型的异常而捕获一个异常。通过阅读文档,用户知道如果
文档
没有合适的方法,那么
方法
可能会引发
属性错误
,而
mypy
可以帮助捕获错误,而无需运行代码。

对于小型甚至中型项目,最好使用duck键入,大型项目的PEP484+mypy

例如:

以及:


顺便说一句,如果您已经有一个没有PEP484类型注释的大型项目,您可以使用MonkeyType之类的东西来添加它们。

使用ducktyping,否则大多数代码将只包含类型注释checks@BlackBear是一个主要由
try。。。除了AttributeError(属性错误)
比主要由类型检查组成的代码要好吗?实际上,这两种代码都不是duck类型。Duck类型表示您使用对象时假定其类型正确(其中“correct”表示“具有此特定函数所需的属性”)。如果它不具有相同的类型,则会引发错误,但您可能会在其他点发生编程错误。如果您愿意,您可以使用,但关键是每个函数/类都假定它将被正确使用(当然它不是“安全的”,但它不能是动态语言)。@DeepSpace无需尝试,只需总结一下(我认为)@jdehesa的意思(如果可以的话),这两种方法都不是“惯用的”-只需使用对象,并允许在传递错误类型的参数时引发异常。调用者可以在必要时处理它们。@busukxuan:有关更多信息,请参阅我的相关主题的问题。因此,在duck类型的原理中,如果类的用户传入错误的类型,则会看到从调用堆栈的6或7层弹出一个奇怪的异常,告诉他们他们的字体错了,这并不是课堂作者的责任,对吗?@Busukhuan:是的。
python3 -m mypy --disallow-untyped-calls ${files}
def pad(number: int) -> str: