Pythonic 方式与常识。类型检查

Pythonic way vs common sense. Type checking

我看到了很多问题,例如以下一个:What's the canonical way to check for type in Python?

而且总是有人回答类似这样的问题:"The pythonic way of checking types is not checking them. and here goes another passage about duck typing."

首先,我确实了解 duck typing 的优点,而且我确实经常使用它。但是不检查类型真的值得吗?

假设我有以下代码:

class DuckA:
    def quack():
        print("QuackA")

class DuckB:
    def quack():
        print("QuackB")

def duck_creator():
    return DuckA()

def duck_client(duck):
    duck.quack()

if __name__ is "__main__":
    duck_client(DuckA())           #ok
    duck_client(DuckB())           #ok
    duck_client(duck_creator())    #ok

    #totally fine untill you actually call it,
    #which might be quite tricky to check in 
    #relatively big project
    duck_client(duck_creator)     

    #one more typo, which is pretty hard to spot
    #from first sight
    duck_client(DuckB)

是的,我知道我们都是工程师,因此,我们支持编写足够的结构,但是各种错别字怎么办?

我是python的初学者,来自c/c++人群。基本上,所有这些涉及鸭子打字的答案对我来说有点像 "if you don't want to spend hours in debugger, you just need to write code without errors"。

那么,python 大师们,有什么 valid/pythonic/accepted 技巧可以克服这样的事情吗?

我见过各种类型检查器,它们已经足够好了,尽管我不喜欢将项目绑定到其中一个 IDE 的想法。

函数开头的断言在我看来确实很有前途。

还有其他想法吗?

我认为您正在寻找的是 Mypy,一个适用于 Python 2.7+/3.4+ 的静态类型检查器。它是 Python 3.6 的注释系统设计的类型检查器,但他们一直小心翼翼地确保它可以与旧版本的 Python 一起使用。 (事实上​​,类型提示的部分动机首先是 Guido 希望使用 Mypy 来帮助指导将大型代码库从 2.7 升级到 3.5。)

当然你不能在旧版本的 Python 中使用 3.6 语法。在 3.5 中,参数可以被注释,但不能是局部变量。在 3.4 中,注释是有限的。在 2.7 中,注释根本不存在。

如果你阅读文档,有几种方法可以解决这个问题,但基本思想是将所有注释放入 "public" 代码的注释中,同时编写 "typeshed" 个文件"internal" 个代码的 out-of-line 个注释。

好消息是,由于 Mypy 得到了核心语言的支持,其他静态类型检查器和相关工具,如 IDE 索引器或更深入的静态分析器,正在适应以相同的方式做事,因此,无论您用于 2.7 或 3.4 代码的是什么,都可能会与您最喜欢的 IDE 或 vim 插件或分析器或其他任何东西一起工作(如果不是今天,那么很快)。