Anotación de tipo correcto para __init__

4 minutos de lectura

¿Cuál es la anotación de tipo correcta para un __init__ función en python?

class MyClass:
    ...

¿Cuál de los siguientes tendría más sentido?

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

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

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

Dado que normalmente instanciaríamos como myclass = MyClass()pero el __init__ La función en sí no tiene valor de retorno.

  • Por mi propia curiosidad, ¿es esto necesario/esperado?

    – Rogan Josh

    16 oct 2017 a las 21:07


  • @roganjosh No, es una función compatible. Lo encuentro útil ya que ayuda a mi IDE (pycharm) a detectar discrepancias de tipo. stackoverflow.com/questions/32557920/…

    – colgar

    16/10/2017 a las 21:15

  • Pero ha etiquetado esto como 2.7, que ni siquiera admite sugerencias de tipo. Sin embargo, mi pregunta era más amplia, que no estoy seguro de que sea útil para __init__().

    – Rogan Josh

    16 oct 2017 a las 21:17

  • @roganjosh, tienes razón, no es útil en este ejemplo. Sin embargo, generalmente lo extendería a otros __init__ funciones que toman variables. Puedo usar algunas funcionalidades instalando mecanografía y pycharm en 2.7.

    – colgar

    16 oct 2017 a las 21:24


  • @roganjosh Python 2 sí admite sugerencias de tipo, consulte documentos mypy Creo que se debe agregar la escritura siempre que sea posible, especialmente para cosas como __init__ y cosas como clases llamables.

    – Davos

    4 de junio de 2018 a las 14:22

avatar de usuario
remram

self debe omitirse de la anotación cuando se da como comentario, y __init__() debe marcarse como -> None. Todo esto está especificado explícitamente en PEP-0484.

  • PEP 484 dice que el tipo de retorno debe anotarse como -> Noneeso no self debe omitirse.

    – usuario2357112

    16 oct 2017 a las 21:24

  • De hecho, la regla no se establece explícitamente. pero se dan ejemplos aquí que omiten self

    – remram

    16 oct 2017 a las 21:27


  • Esos ejemplos muestran el código de Python 3 usando self en la firma del método y -> None como tipo de retorno, que es lo que debe hacer. Si desea compatibilidad con Python 2, puede colocar la firma de tipo en un comentario y, en ese caso, omitiría self en la signatura tipo comentada. Ciertamente no dejarías de lado self en los parámetros del método, o obtendrá errores de desajuste de conteo de parámetros porque el primer parámetro tomará el lugar de sí mismo. Lo que sea que etiquetes, no importa, es solo self por convención. Probablemente quisiste decir eso, pero no estaba claro.

    – Davos

    4 de junio de 2018 a las 14:18


  • ¿Podría aclarar eso con “self debe ser omitido”. De hecho, quiere decir no omitir el self parámetro, pero para omitir la sugerencia de tipo para self?

    – TheDiveO

    14 de junio de 2018 a las 11:32

  • De paso, mypy permite omitir ` -> Ninguno` de __init__ – aunque muy discutido – por la razón de que __init__ solo puede tener este tipo de devolución (para la verificación de tipo ` -> Ninguno` se agrega automáticamente), consulte github.com/python/mypy/issues/604

    – F.Raab

    21 de mayo de 2019 a las 18:14

Si está utilizando Python 3 (espero que lo haga), no hay necesidad de anotar __init__ desde el lanzamiento de mypy 0.641 si hay al menos un argumento anotadosiempre debe ser None, porque no devuelve nada. En otros casos, mypy generará un error. Este comportamiento molestó a la gente durante años, pero finalmente se solucionó.

Esto es lo que Guido dice:

Nueva función: Permitir omitir el tipo de retorno para __init__ Ahora es posible omitir el tipo de retorno de un anotado __init__ método sin obtener un mensaje de error. Por ejemplo:

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

En versiones anteriores de mypy, esto generaría un mensaje de error:

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

Este error fue simplemente molesto como la única declaración de devolución legal para
__init__ es -> Ninguno, por lo que lo hemos eliminado. ¡Tenga en cuenta que esto solo funciona si hay al menos un argumento anotado! Para __init__ métodos sin argumentos aún debe agregar -> Ninguno, de lo contrario, el método se tratará como sin tipo, y su cuerpo no se verificará en absoluto. Ejemplos:

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

Discusiones relacionadas:

  1. Permitir __init__ con firma pero sin tipo de retorno
  2. A la función le falta la anotación de tipo para __init__(uno mismo)

¿Ha sido útil esta solución?