functions español classes python class

español - python import class



__new__ y__init__ en Python (1)

cómo debería estructurar la clase usando __init__ y __new__ ya que son diferentes y ambos aceptan argumentos arbitrarios además del primer argumento predeterminado.

Solo en raras ocasiones tendrás que preocuparte por __new__ . Por lo general, usted simplemente definirá __init__ y dejará que __new__ predeterminado __new__ pase los argumentos del constructor.

self palabra clave self es en términos de nombre puede ser cambiado a algo más? Pero me pregunto si cls está en términos de nombre está sujeto a cambiar a otra cosa, ya que es solo un nombre de parámetro.

Ambos son solo nombres de parámetros sin significado especial en el idioma. Pero su uso es una convención muy fuerte en la comunidad de Python; la mayoría de los Pythonistas nunca cambiarán los nombres de self y los cls en estos contextos y se confundirán cuando alguien más lo haga.

Tenga en cuenta que el uso de def __new__(tuple) vuelve a def __new__(tuple) el nombre tuple dentro de la función constructora. Cuando realmente implemente __new__ , querrá hacerlo como

def __new__(cls, *args, **kwargs): # do allocation to get an object, say, obj return obj

Aunque dije que quería devolver la tuple , este código funciona bien y me devolvió [1,2,3] .

MyClass() tendrá el valor que devuelve __new__ . No hay verificación de tipos implícita en Python; es responsabilidad del programador devolver el tipo correcto ("todos consentimos adultos aquí"). Ser capaz de devolver un tipo diferente al solicitado puede ser útil para implementar fábricas: puede devolver una subclase del tipo solicitado.

Esto también explica el comportamiento issubclass / isinstance que observa: la relación de subclase se desprende de su uso de la class MyClass(tuple) , la isinstance refleja que usted devuelve el tipo "incorrecto" de __new__ .

Como referencia, consulte los requisitos para __new__ en la Referencia del lenguaje Python .

Editar : bien, aquí hay un ejemplo del uso potencialmente útil de __new__ . La clase Eel realiza un seguimiento de cuántas anguilas están vivas en el proceso y se rehúsa a asignar si excede un máximo.

class Eel(object): MAX_EELS = 20 n_eels = 0 def __new__(cls, *args, **kwargs): if cls.n_eels == cls.MAX_EELS: raise HovercraftFull() obj = super(Eel, cls).__new__(cls) cls.n_eels += 1 return obj def __init__(self, voltage): self.voltage = voltage def __del__(self): type(self).n_eels -= 1 def electric(self): """Is this an electric eel?""" return self.voltage > 0

Eso sí, hay formas más inteligentes de lograr este comportamiento.

Estoy aprendiendo Python y hasta ahora puedo decir lo siguiente sobre __new__ y __init__ :

  1. __new__ es para creación de objetos
  2. __init__ es para la inicialización de objetos
  3. __new__ se invoca antes de __init__ como __new__ devuelve una nueva instancia y __init__ invoca después para inicializar el estado interno.
  4. __new__ es bueno para objetos inmutables ya que no se pueden cambiar una vez que se asignan. Entonces podemos devolver una nueva instancia que tiene un nuevo estado.
  5. Podemos usar __new__ y __init__ para ambos objetos mutables ya que su estado interno puede ser cambiado.

Pero tengo otra pregunta ahora.

  1. Cuando creo una nueva instancia como a = MyClass("hello","world") , ¿cómo se pasan estos argumentos? Quiero decir cómo debería estructurar la clase usando __init__ y __new__ ya que son diferentes y ambos aceptan argumentos arbitrarios además del primer argumento predeterminado.
  2. self palabra clave self es en términos de nombre puede ser cambiado a algo más? Pero me pregunto si cls está en términos de nombre está sujeto a cambiar a otra cosa, ya que es solo un nombre de parámetro.

Hice algunos pequeños experimentos como tales a continuación:

>>> class MyClass(tuple): def __new__(tuple): return [1,2,3]

y lo hice a continuación:

>>> a = MyClass() >>> a [1, 2, 3]

Aunque dije que quería devolver la tuple , este código funciona bien y me devolvió [1,2,3] . Sabía que estábamos pasando los primeros parámetros como el tipo que queríamos recibir una vez que se invoca la función __new__ . Estamos hablando de una New función, ¿verdad? No sé otro tipo de devolución de idiomas que no sea el tipo vinculado

Y también hice otras cosas:

>>> issubclass(MyClass,list) False >>> issubclass(MyClass,tuple) True >>> isinstance(a,MyClass) False >>> isinstance(a,tuple) False >>> isinstance(a,list) True

No hice más experimento porque el más allá no era brillante y decidí parar allí y decidí pedir StackOverflow.

Los mensajes SO que leo:

  1. Creación de objetos en Python
  2. ¿El uso de Python de __new__ y __init__?