python - español - pep8 pdf
¿Por qué__new__ en las clases de estilo nuevo de Python no es un método de clase? (1)
__new__
siendo el método estático permite un caso de uso cuando se crea una instancia de una subclase:
return super(<currentclass>, cls).__new__(subcls, *args, **kwargs)
Si new
es un método de clase, lo anterior se escribe como:
return super(<currentclass>, cls).new(*args, **kwargs)
y no hay lugar para poner subcls
.
Aunque no veo realmente cuándo sería un uso adecuado de
__new__
. Tal vez no lo estoy viendo, pero me parece que es un uso completamente patológico de él (y debería decirse, que si realmente lo quieres, entonces podrías acceder a él con elobject.__new__.__func__
). Por lo menos, me resulta muy difícil imaginar que hubiera sido la razón por la que Guido cambiara__new__
de ser un método de clase a un método estático.
Un caso más común sería llamar al padre __new__
sin usar super()
. Necesitas un lugar para pasar cls
explícitamente en este caso :
class Base(object):
@classmethod
def new(cls):
print("Base.new(%r)" % (cls,))
return cls()
class UseSuper(Base):
@classmethod
def new(cls):
print("UseSuper.new(%r)" % (cls,))
return super(UseSuper, cls).new() # passes cls as the first arg
class NoSuper(Base):
@classmethod
def new(cls):
print("NoSuper.new(%r)" % (cls,))
return Base.new() # passes Base as the first arg
class UseFunc(Base):
@classmethod
def new(cls):
print("UseFunc.new(%r)" % (cls,))
return Base.new.im_func(cls) # or `.__func__(cls)`. # passes cls as the first arg
print(UseSuper.new())
print(''-''*60)
print(NoSuper.new())
print(''-''*60)
print(UseFunc.new())
El registro de cambios para Python 2.2 (donde se introdujeron las clases de estilo nuevo) dice lo siguiente acerca de la función __new__
:
__new__
es un método estático, no un método de clase. Inicialmente pensé que tendría que ser un método de clase, y es por eso que agregué el primitivoclassmethod
. Desafortunadamente, con los métodos de clase, las llamadas ascendentes no funcionan bien en este caso, así que tuve que convertirlo en un método estático con una clase explícita como primer argumento.
Sin embargo, no puedo pensar por qué los métodos de clase no funcionarían para este propósito, y sin duda se verían mejor. ¿Por qué no __new__
terminó como un método de clase al final? ¿A qué se refiere Guido cuando dice que "las llamadas hacia arriba no funcionan bien en este caso"?