【发布时间】:2018-03-11 20:48:32
【问题描述】:
我见过很多问题,比如以下一个:What's the canonical way to check for type in Python?
而且总是有人这样回答:“检查类型的 Pythonic 方法不是检查它们。这里还有一段关于鸭子类型的文章。”
首先,我确实了解鸭式打字的优点,而且我确实经常使用它。但是不检查类型真的值得吗?
假设我有以下代码:
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++ 人群。基本上,所有这些涉及鸭子打字的答案对我来说听起来有点像“如果你不想在调试器上花费数小时,你只需要编写没有错误的代码”。
那么,python 大师们,是否有任何有效的/pythonic/公认的技术来克服这样的事情?
我见过各种各样的类型检查器,它们已经足够好了,尽管我不喜欢将项目绑定到其中一个 ide 的想法。
从我的角度来看,函数开头的断言确实看起来很有希望。
还有其他想法吗?
【问题讨论】:
-
如果您非常担心拼写错误,请养成在 IDE 中使用 python3.6 的打字检查的习惯。
-
如果您有拼写错误,您的代码将因 NameError 或 AttributeError 或其他一些容易诊断的故障而失败。一个简单的测试就足以暴露这一点。
-
python 3.6 并不总是可用的问题。现在,假设几个团队成员更喜欢使用 vim 或类似的东西。是的,正如@DanielRoseman 指出的那样,它会失败。问题是它可能在编写代码几个月后失败(假设有人进行了导致回归的更改)。当然,这可能会被自动测试覆盖,但在实际项目中,您可能无法提供 100% 的覆盖率。
-
这里的论点部分确实是一个主观问题,但是……根据我的经验,您计划为其编写断言的类型检查不会捕捉到您遇到的错误实际上要做。你得到的只是相对弱的类型系统(如 C++ 或 Java,而不是 Rust 或 Haskell)中的静态类型给你的那种错误的安全感:你的代码可以编译,但它仍然充满了引用/线程/等.错误,这就是为什么 Java 中的空指针异常比 Python 中的 None 上的 AttributeErrors 更多。
-
无论如何,如果 Python 3.6 不可用,为什么不能使用向后兼容的 MyPy 语法,将类型注释作为 cmets 或在 typesheds 中?当然,它有点难看,但是“我想使用 Python 2.7 或 3.4,它使 Python 3.6 的功能有点难看”是使用 Python 3.6 的论据,而不是讨厌这些功能的论据。
标签: python types duck-typing