Python EAFP和mypy可以共存吗? EAFP

Python EAFP和mypy可以共存吗? EAFP,python,mypy,python-typing,duck-typing,Python,Mypy,Python Typing,Duck Typing,请求原谅比允许更容易。这种常见的Python编码风格假设存在有效的键或属性,如果假设为false,则捕获异常。这种简洁快速的风格的特点是有许多尝试和例外的陈述。这种技术与许多其他语言(如C语言)所共有的LBYL风格形成对比 什么是mypy? Mypy是Python的可选静态类型检查器。您可以将类型提示()添加到Python程序中,并使用mypy静态地进行类型检查。甚至不用运行程序就可以发现程序中的错误 您可以在程序中混合使用动态和静态键入。当静态类型不方便时,例如对于遗留代码,您总是可以返回到

请求原谅比允许更容易。这种常见的Python编码风格假设存在有效的键或属性,如果假设为false,则捕获异常。这种简洁快速的风格的特点是有许多尝试和例外的陈述。这种技术与许多其他语言(如C语言)所共有的LBYL风格形成对比

什么是mypy? Mypy是Python的可选静态类型检查器。您可以将类型提示()添加到Python程序中,并使用mypy静态地进行类型检查。甚至不用运行程序就可以发现程序中的错误

您可以在程序中混合使用动态和静态键入。当静态类型不方便时,例如对于遗留代码,您总是可以返回到动态类型

下面是一段关于EAFP的精彩YouTube视频:

我试图使用mypy,但基本上每次我写一些EAFP代码时,它都会生气

例如:

从contextlib导入抑制
从键入导入可选
类别MyClass:
定义初始化(自):
self.\u name:可选[str]=无
@财产
def名称(自身)->可选[str]:
返回self.\u名称
@姓名设定器
def名称(self,名称:str):
self.\uu name=名称
@财产
def upper_名称(自身)->可选[str]:
使用抑制(AttributeError):
返回self.name.upper()#“Optional[str]”的项“None”没有属性“upper”-mypy(错误)
一无所获
在本例中,我希望
upper\u name
属性尝试将
name
转换为大写,但是如果
name
None
,它将引发一个
AttributeError
,然后被
suppress(AttributeError)
抑制,因此函数返回
None

我在底部显示了explicit
return None
,因为它表示:

在返回语句中保持一致。函数中的所有return语句都应该返回表达式,或者都不应该返回。如果任何return语句返回表达式,则没有返回值的任何return语句都应显式地将其声明为return None,并且在函数的末尾应显示一个显式的return语句(如果可以访问)

我已经提交了一个,但它几乎立即关闭

我确实认为有可能让
mypy
了解EAFP

例如,如果它看到一个类型
可选的[something]
,并且它看到一个表达式,如果它接收到
None
,则会引发
somethingeror
,但如果它接收到
something
,则会成功,该表达式包含在一个
try
suppress
块中,该块可以处理
somethingeror
,然后它可以假设它是某个EAFP代码,而不是异常

但现在的情况是,为了不被上面的例子吓坏,我必须将它改为:

从输入导入可选
类别MyClass:
定义初始化(自):
self.\u name:可选[str]=无
@财产
def名称(自身)->可选[str]:
返回self.\u名称
@姓名设定器
def名称(self,名称:str):
self.\uu name=名称
@财产
def upper_名称(自身)->可选[str]:
如果self.name不是None:
返回self.name.upper()
其他:
一无所获
另一个例子:

假设我可以有一个
房子
,可以有一个
车库
,可以有一辆
汽车
,有一个
品牌
,这样我就可以得到它的
品牌

从contextlib导入抑制
从我的公寓
汽车品牌=无
尝试:
汽车
除属性错误外:
通过
其他:
汽车品牌
如果
房屋
,或者
车库
,或者
汽车
汽车品牌
将保持
。但是如果有一个
房子
有一个
车库
有一辆
汽车
,它会尝试获得它的
品牌
。如果
汽车
没有
品牌
,则不会抑制该错误,因为
汽车
必须有
品牌

另一种方法是避免出现
mypy
错误:

来自my_模块导入公司
汽车品牌=无
如果房子不是空的:
车库
如果车库不是无:
汽车
如果car不是无:
汽车品牌
我不认为这是非常可读或干净的

另一点我认为是有效的是避免比赛条件。如果我首先读取一个值来检查它是否有效,然后再次读取以使用它,如果它有效,我相信没有任何东西可以保证我第二次读取它时,我将收到与第一次相同的值

用“EAFP”的方式做事情时,我只读取一次值,所以在我读取值之后,值是否会发生剧烈变化并不重要

我的例子并不完美,但我认为它们在传达理念方面起到了关键作用

因此,我的问题是,如何使用EAFP样式并仍然使用
mypy
?是否有一个标志或参数我可以给
mypy
,这样它就不会在仅仅存在EAFP的情况下崩溃?还是有一种“更好”的EAFP做事方式,不会让mypy感到悲伤

  • Python
    3.8.6
  • mypy
    0.782

首先,mypy(通常是静态键入)不要求许可或原谅,而是鼓励您两者都不做:您设计代码,以确保您想要执行的操作100%成功。例如,在您的情况下,我会尝试将
self.name
设置为
str
类型,而不是
Optional[str]
,以避开pro