正确的__ init__ 的类型注释

Python 中 __init__函数的正确类型注释是什么?

class MyClass:
...

下列哪一个更有意义?

def __init__(self):
# type: (None) -> None


def __init__(self):
# type: (MyClass) -> MyClass


def __init__(self):
# type: (None) -> MyClass

因为我们通常实例化为 myclass = MyClass(),但是 __init__函数本身没有返回值。

36552 次浏览

self should be omitted from the annotation when it is given as a comment, and __init__() should be marked as -> None. This is all specified explicitly in PEP-0484.

If you're using Python 3 (I hope you do), no need to annotate __init__ method at all since mypy 0.641 release if there's at least one annotated argument, it must always be None, because it returns nothing. In other cases, mypy will raise an error. This behavior annoyed people for years but eventually it was fixed.

This is what Guido says:

New Feature: Allow Omitting Return Type for __init__ It is now possible to omit the return type of an annotated __init__ method without getting an error message. For example:

class Circuit:
def __init__(self, voltage: float):
self.voltage = voltage

In previous mypy versions this would elicit an error message:

error: The return type of "__init__" must be None

This error was just annoying as the only legal return declaration for __init__ is -> None, so we’ve removed it. Note that this only works if there’s at least one annotated argument! For __init__ methods without arguments you must still add -> None, otherwise the method will be treated as untyped, and its body will not be type checked at all. Examples:

class UntypedExample:
# This method is not type-checked at all!
def __init__(self):
self.voltage = 0.0


class TypedExample:
# This is how to ensure that a 0-argument __init__ is type-checked:
def __init__(self) -> None:
self.voltage = 0.0

Related discussions:

  1. Allow __init__ with signature but no return type
  2. Function is missing type annotation for __init__(self)