为什么我们应该在 def __init__(self, n) -> None: 中使用 ->
Why should we use -> in def __init__(self, n) -> None:?
为什么要在def __init__(self, n) -> None:
中使用->
?我阅读了以下摘录 from PEP 484,但我无法理解其含义。
(Note that the return type of __init__
ought to be annotated with
-> None
. The reason for this is subtle. If __init__
assumed a
return annotation of -> None
, would that mean that an argument-less,
un-annotated __init__
method should still be type-checked? Rather
than leaving this ambiguous or introducing an exception to the
exception, we simply say that __init__
ought to have a return
annotation; the default behavior is thus the same as for other
methods.)
使用 def __init__(self, n) -> None:
和 def __init__(self, n):
之间的细微差别是什么?谁能用简单的话解释引用的摘录?
这仅在您关心类型注释时才重要,如果您不关心则可以跳过。它不会在运行时更改功能(除了在私有 __annotations__
属性 中添加信息)。
那它有什么作用?
->
用来记录一个函数returns.
的数据类型
然后是类型,在您的情况下,类型是 None
.
所以它说该方法没有 return 任何东西,或者如果它有 return 东西它总是 None
.
如果你想要return一些东西,你会把它改成return集的类型。
在python3.5出现了type annotation选项。 def __init__(self, n) -> None:
意味着 __init__
应该总是 return None 类型,如果你不小心 return 一些不同于 None 的东西,它会很有帮助,特别是如果你使用 mypy 或其他类似的东西。但如果你更喜欢老方法,你可以忽略它。
它归结为 PEP 484 - The meaning of annotations 中的第一句话 任何类型检查器都应将任何没有注释的函数视为具有最通用的类型,或者忽略。 def __init__(self, n):
不会被检查,但 def __init__(self, n) -> None:
会。即使我们知道 __init__
应该只 return None
,检查器也不应该对它进行特殊处理。原因是你不知道作者有没有打算def __init__(self):
勾选
主要是为了允许静态类型检查。默认情况下,mypy
将忽略未注释的函数和方法。
考虑以下定义:
class Foo:
def __init__(self):
return 3
f = Foo()
mypy
,静态类型分析工具,默认看这个没什么问题:
$ mypy tmp.py
Success: no issues found in 1 source file
但是它产生了运行时TypeError
(注意这里的python
是Python3.8.6):
$ python tmp.py
Traceback (most recent call last):
File "tmp.py", line 5, in <module>
f = Foo()
TypeError: __init__() should return None, not 'int'
如果添加注释 -> None
,则 mypy
将对方法进行类型检查并引发错误:
$ mypy tmp.py
tmp.py:3: error: No return value expected
Found 1 error in 1 file (checked 1 source file)
如果您试图通过声明 def __init__(self) -> int:
来规避检查,mypy
甚至会抱怨:
$ mypy tmp.py
tmp.py:2: error: The return type of "__init__" must be None
Found 1 error in 1 file (checked 1 source file)
还值得注意的是,任何注释都会使mypy
注意;如果您至少有一个带注释的参数,则缺少 return 类型与 -> None
相同:
def __init__(self, x: int):
return x
将产生与显式 -> None
相同的“No return value expected”错误。不过,显式 return 类型通常比任何人为的参数类型提示更容易提供,并且可以说比尝试键入 self
.
更清晰
对此事的批判性阅读是 MyPy issue 604 中包括 Guido 在内的帖子,他认为
I still think __init__
is a special case -- its return value is determined by how Python uses it, not by what the user might want it to return. I think the absence of -> None
should never result in an error message here
结束于
gvanrossum added a commit that referenced this issue on Oct 1, 2018 [...]
Make return type implicitly None
for type checked __init__
长话短说,如果 linter 确定对于给定的 __init__
可以进行静态类型检查(在您的情况下通过添加 n: int
),它不会 - 也不应该 - 抱怨在没有 -> None
的情况下,将推断出
为什么要在def __init__(self, n) -> None:
中使用->
?我阅读了以下摘录 from PEP 484,但我无法理解其含义。
(Note that the return type of
__init__
ought to be annotated with-> None
. The reason for this is subtle. If__init__
assumed a return annotation of-> None
, would that mean that an argument-less, un-annotated__init__
method should still be type-checked? Rather than leaving this ambiguous or introducing an exception to the exception, we simply say that__init__
ought to have a return annotation; the default behavior is thus the same as for other methods.)
使用 def __init__(self, n) -> None:
和 def __init__(self, n):
之间的细微差别是什么?谁能用简单的话解释引用的摘录?
这仅在您关心类型注释时才重要,如果您不关心则可以跳过。它不会在运行时更改功能(除了在私有 __annotations__
属性 中添加信息)。
那它有什么作用?
->
用来记录一个函数returns.
的数据类型
然后是类型,在您的情况下,类型是 None
.
所以它说该方法没有 return 任何东西,或者如果它有 return 东西它总是 None
.
如果你想要return一些东西,你会把它改成return集的类型。
在python3.5出现了type annotation选项。 def __init__(self, n) -> None:
意味着 __init__
应该总是 return None 类型,如果你不小心 return 一些不同于 None 的东西,它会很有帮助,特别是如果你使用 mypy 或其他类似的东西。但如果你更喜欢老方法,你可以忽略它。
它归结为 PEP 484 - The meaning of annotations 中的第一句话 任何类型检查器都应将任何没有注释的函数视为具有最通用的类型,或者忽略。 def __init__(self, n):
不会被检查,但 def __init__(self, n) -> None:
会。即使我们知道 __init__
应该只 return None
,检查器也不应该对它进行特殊处理。原因是你不知道作者有没有打算def __init__(self):
勾选
主要是为了允许静态类型检查。默认情况下,mypy
将忽略未注释的函数和方法。
考虑以下定义:
class Foo:
def __init__(self):
return 3
f = Foo()
mypy
,静态类型分析工具,默认看这个没什么问题:
$ mypy tmp.py
Success: no issues found in 1 source file
但是它产生了运行时TypeError
(注意这里的python
是Python3.8.6):
$ python tmp.py
Traceback (most recent call last):
File "tmp.py", line 5, in <module>
f = Foo()
TypeError: __init__() should return None, not 'int'
如果添加注释 -> None
,则 mypy
将对方法进行类型检查并引发错误:
$ mypy tmp.py
tmp.py:3: error: No return value expected
Found 1 error in 1 file (checked 1 source file)
如果您试图通过声明 def __init__(self) -> int:
来规避检查,mypy
甚至会抱怨:
$ mypy tmp.py
tmp.py:2: error: The return type of "__init__" must be None
Found 1 error in 1 file (checked 1 source file)
还值得注意的是,任何注释都会使mypy
注意;如果您至少有一个带注释的参数,则缺少 return 类型与 -> None
相同:
def __init__(self, x: int):
return x
将产生与显式 -> None
相同的“No return value expected”错误。不过,显式 return 类型通常比任何人为的参数类型提示更容易提供,并且可以说比尝试键入 self
.
对此事的批判性阅读是 MyPy issue 604 中包括 Guido 在内的帖子,他认为
I still think
__init__
is a special case -- its return value is determined by how Python uses it, not by what the user might want it to return. I think the absence of-> None
should never result in an error message here
结束于
gvanrossum added a commit that referenced this issue on Oct 1, 2018 [...] Make return type implicitly
None
for type checked__init__
长话短说,如果 linter 确定对于给定的 __init__
可以进行静态类型检查(在您的情况下通过添加 n: int
),它不会 - 也不应该 - 抱怨在没有 -> None
的情况下,将推断出