nomenclatura español python new-operator language-design new-style-class

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 el object.__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 primitivo classmethod . 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"?