2010-06-28 13 views
26

Entiendo cómo funcionan __init__ y __new__. Me pregunto si hay algo __init__ que pueda hacer que __new__ no?Python: siempre use __new__ en lugar de __init__?

es decir, se puede utilizar de __init__ se sustituye por el siguiente patrón:

class MySubclass(object): 
    def __new__(cls, *args, **kwargs): 
     self = super(MySubclass, cls).__new__(cls, *args, **kwargs) 
     // Do __init__ stuff here 
     return self 

estoy pidiendo que me gustaría hacer este aspecto de Python OO encaja mejor en mi cabeza.

+0

posible duplicado de [por qué se definió '\ _ \ _ new__' y '\ _ \ _ init__' todo en una clase] (http: // stackoverflow.com/questions/2017876/why-defined-new-and-init-all-in-a-class) –

+0

Pregunta anterior sobre ese tema: [El uso de Python de \ _ \ _ new__ y \ _ \ _ init__?] (http://stackoverflow.com/questions/674304/pythons-use-of-new-and-init) –

Respuesta

4

Una posible respuesta de guido's post (gracias @ fraca7):

Por ejemplo, en el módulo de la salmuera, __new__ se utiliza para crear instancias cuando revertir la seriación objetos. En este caso, se crean instancias, pero el método __init__ no se invoca.

¿Alguna otra respuesta similar?


que estoy aceptando esta respuesta como un 'sí' a mi propia pregunta:

Me pregunto si hay algo que puede hacer que __init____new__ no se puede?

Sí, a diferencia de __new__, las acciones que se pone en el método __init__ no se realizará durante el proceso de desestibado. __new__ no puede hacer esta distinción.

2

Bien, buscando __new__ vs __init__ en google me mostró this.

La historia larga corta, __new__ devuelve una nueva instancia de objeto, mientras que __init__ no devuelve nada y solo inicializa los miembros de la clase.

EDITAR: Para responder realmente a su pregunta, nunca debería necesitar anular __new__ a menos que esté subclasificando tipos inmutables.

+1

Guido habló de eso recientemente: http://python-history.blogspot.com/2010/06/inside-story- on-new-style-classes.html – fraca7

+2

Existen otras razones para usar '__new__', por ejemplo, el patrón flyweight. –

21

Por lo tanto, la clase de una clase es típicamente type, y cuando se llama al método Class()__call__() en clase Class 's que maneja. Creo type.__call__() se implementa más o menos así:

def __call__(cls, *args, **kwargs): 
    # should do the same thing as type.__call__ 
    obj = cls.__new__(cls, *args, **kwargs) 
    if isinstance(obj, cls): 
     obj.__init__(*args, **kwargs) 
    return obj 

La respuesta directa a su pregunta es no, las cosas que __init__() puede hacer (/ cambio de "inicializar" una instancia especificada) es un subconjunto de las cosas que __new__() puede hacer (crear o seleccionar cualquier objeto que desee, hacer cualquier cosa con ese objeto que desee antes de que se devuelva el objeto).

Sin embargo, es conveniente tener ambos métodos para usar. El uso de __init__() es más simple (no tiene que crear nada, no tiene que devolver nada), y creo que es una buena práctica usar siempre __init__() a menos que tenga un motivo específico para usar __new__().

+0

Para mí, esto realmente no responde la pregunta del OP. Usted dijo que "las cosas que' __init__() 'pueden hacer es un subconjunto de las cosas que' __new___() 'puede hacer", pero ese es precisamente el punto del OP, ¿no es así? Si esa oración es verdadera, entonces '__init __()' puede ser desaprobada de manera segura, porque cualquier cosa que pueda hacer, '__new __()' puede funcionar igual de bien. – Ray

+0

@Ray ** Su conclusión no se desprende de su premisa. ** Mientras que la oración * es * ostensiblemente verdadera, '__init__()' no puede ser desaprobada de manera segura por todas las razones obvias, en particular, ** (A) ** la necesidad de preservar la compatibilidad con el ecosistema Python existente * y * ** (B) ** la fragilidad contractual de la API '__new __()' (cuyo diseño exige que se devuelva explícitamente una instancia) contra el '__init __()' API (cuyo diseño no impone tales restricciones). '__new __()' invita a violaciones de API, lo cual es malo; '__init __()' does * not *, que es bueno. –

Cuestiones relacionadas