我一直想知道在Python 3.11中声明变量类型而不直接赋值的最Pythonic方式和最易读的方式是什么
上过课
class MyClass:
def __init__(self, value: str):
self.value: str = value
我可以声明变量而不分配值:
def test():
variable: MyClass
if True:
variable = MyClass(value="value")
else:
variable = MyClass(value="otherValue")
这可行,但在尝试使用它时该变量不存在,因此它的存在只是为了可读性。我可以使用可选
def test():
variable: Optional[MyClass] = None
if True:
variable = MyClass(value="value")
else:
variable = MyClass(value="otherValue")
assert isinstance(variable, MyClass)
或者我可以在第一次使用时输入
def test():
if True:
variable: MyClass = MyClass(value="value")
else:
variable = MyClass(value="otherValue")
我在Peps中找不到任何东西,chatGpt4自相矛盾,google将我发送到2015年GitHub的问题。 MyPy 工具似乎对这三个都很好,但我想知道,有没有“正确”的方法?
谢谢!
variable: MyClass
使用Optional和None赋值:
variable: Optional[MyClass] = None
首次使用时输入:
variable: MyClass = MyClass(a="value")
在存根中声明变量的存在可能很有用 而不给它初始值。这可以使用 PEP 526 来完成 变量注释语法:所以“正确”的方式似乎是
from typing import IO stream: IO[str]
上述语法在所有 Python 版本的存根中都是可接受的。 但是,在 Python 3.5 及更早版本的非存根代码中 是一个特例:
from typing import IO stream = None # type: IO[str]
类型检查器不应该抱怨这一点(尽管值 None 不匹配给定的类型),也不应该更改推断的类型 到可选[...](尽管规则为带注释的 默认值为 None 的参数)。这里的假设是 其他代码将确保变量被赋予一个值 正确的类型,并且所有用途都可以假设该变量具有给定的 类型。
def test():
variable = None # type: MyClass
if True:
variable = MyClass(value="value")
else:
variable = MyClass(value="otherValue")
所以看来我们仍然使用评论作为打字的方式,我个人不太喜欢这种方式。
就我个人而言,我认为第一种方法是三种方法中最好的,因为它遵循经典的“在顶部声明变量”原则,允许看起来对称的分支,并且不需要初始的、不必要的值。
另一方面,这并不是我能想到的最 Pythonic 的方式。如果您的条件分支足够简单,您可以完全省略类型提示并让类型检查器推断:
def test():
if True:
variable = MyClass(value="value")
else:
variable = MyClass(value="otherValue")
reveal_type(variable) # mypy & pyright => MyClass