2012-01-24 27 views
59

¿Por qué los constructores se llaman realmente "Constructores"? ¿Cuál es su propósito y cómo se diferencian de los métodos en una clase?Python constructors and __init__

Además, ¿puede haber más de uno __init__ en una clase? Intenté algo como lo siguiente, ¿alguien puede explicar el resultado?

>>> class test: 
    def __init__(self): 
     print "init 1" 
    def __init__(self): 
     print "init 2" 


>>> s=test() 
init 2 

Finalmente, se __init__ un overloader operador?

+22

Técnicamente, '__init__' es un * inicializador *. El constructor python * es '__new__'. Python usa la inicialización automática en dos fases - '__new__' devuelve un objeto válido pero (por lo general) no poblado (ver' bool' para un contraejemplo), que luego tiene '__init__' invocado automáticamente. Esto evita los problemas que tienen los lenguajes como C++ con los objetos parcialmente construidos; nunca tiene uno en Python (aunque puede estar parcialmente inicializado). Casi nunca tendrás que anular tanto '__new__' como' __init__' en una clase. –

+2

@TimDelaney: No estoy seguro de qué quiere decir con objetos parcialmente construidos en C++. –

+7

@phresnel En C++, el tipo de objeto es la clase base (no la subclase) mientras está en el constructor de la clase base. No puede llamar a un método virtual en el constructor de la clase base y hacer que la subclase proporcione la implementación. En Java puede llamar a un método de subclase en el constructor de la clase base, pero las variables miembro de la subclase se inicializarán automáticamente * después de * el constructor de la clase base (y la llamada al método). En los lenguajes con inicialización en dos fases como Python, puede invocar métodos en el inicializador de la clase base y hacer que la subclase proporcione (o anule) el comportamiento. –

Respuesta

76

No hay sobrecarga de funciones en Python, lo que significa que no puede tener múltiples funciones con el mismo nombre pero diferentes argumentos.

En el ejemplo del código, no está sobrecargando__init__(). Lo que ocurre es que la segunda definición vuelve a enlazar con el nombre __init__ al nuevo método, haciendo que el primer método sea inaccesible.

En cuanto a su pregunta general sobre constructores, Wikipedia es un buen punto de partida. Para cosas específicas de Python, recomiendo encarecidamente el Python docs.

+0

¿Significa también que el archivo de origen se analiza (¿se interpreta?) Secuencialmente? ¿Puedo estar seguro de que cualquier función que haya definido más adelante sobrescribe la definida con el mismo nombre en anterior? :(mi Q suena tonto ... debería haberlo sabido – 0xc0de

+4

@ 0xc0de: en Python, las definiciones de función son realmente * declaraciones ejecutables * y se ejecutan de arriba a abajo, así que sí. – NPE

+0

Gracias hombre ....... Eso explica el –

7

Las clases son simplemente planos para crear objetos. El constructor es un código que se ejecuta cada vez que crea un objeto. Por lo tanto, no tiene sentido tener dos constructores. Lo que sucede es que el segundo sobre escribe el primero.

Lo que suelen utilizarse para es crear variables para ese objeto como éste:

>>> class testing: 
...  def __init__(self, init_value): 
...   self.some_value = init_value 

Así que lo que podría hacer a continuación es crear un objeto de esta clase como esta:

>>> testobject = testing(5) 

El objeto testobject tendrá un objeto llamado some_value que en este ejemplo será 5.

>>> testobject.some_value 
5 

Pero no necesita establecer un valor para cada objeto como lo hice en mi muestra. También se puede hacer así:

>>> class testing: 
...  def __init__(self): 
...   self.some_value = 5 

entonces el valor de some_value será 5 y no tener que establecer que cuando se crea el objeto.

>>> testobject = testing() 
>>> testobject.some_value 
5 

>>> y ... en mi muestra no es lo que escribes. Es como se vería en Pyshell ...

+0

Esa fue una explicación muy clara ... Gracias hombre ...... –

+0

No hay problema, me alegro de que te haya ayudado:) –

1

coonstructors se llaman automáticamente cuando se crea un nuevo objeto, por lo tanto, "construir" el objeto. La razón puede tener más de un init es porque los nombres son sólo referencias en Python, y se le permite cambiar lo que cada referencias variables siempre que lo desee (tipificación de ahí dinámico)

def func(): #now func refers to an empty funcion 
    pass 
... 
func=5  #now func refers to the number 5 
def func(): 
    print "something" #now func refers to a different function 

en su definición de clase, simplemente mantiene el último

46

¿Por qué los constructores se llaman realmente "Constructores"?

Porque __init__ construye su objeto.

¿En qué se diferencian de los métodos en una clase?

Como se indica en la official documentation__init__ es llamada cuando se crea la instancia, otros métodos no reciben este tratamiento.

¿Cuál es su propósito?

El propósito es permitirle construir su objeto como lo desee en el momento de la creación.

Por ejemplo Python permite que hagas:

class Test(object): 
    pass 

t = Test() 

t.x = 10 # here you're building your object t 
print t.x 

Pero si quieres cada instancia de Test tener un atributo x igual a 10, se puede pyt ese código dentro __init__:

class Test(object): 
    def __init__(self): 
     self.x = 10 

t = Test() 
print t.x 

'self' es simplemente la palabra estándar utilizada como primer argumento de una función de método, eso es porque el primer argumento es la instancia de objeto (excepto class/static -metodos), en nuestro caso t.

Ahora, si se desea que los valores personalizados para el x atribuyen todo lo que tiene que hacer es pasar ese valor como argumento para __init__:

class Test(object): 
    def __init__(self, x): 
     self.x = x 

t = Test(10) 
print t.x 
z = Test(20) 
print t.x 

espero que esto ayudará a aclarar algunas dudas, y ya que' Ya he recibido buenas respuestas a las otras preguntas Me detendré aquí :)

+0

Eso despejó una gran cantidad de conceptos ....... Gracias Señor –

0

No existe la noción de sobrecarga de métodos en Python. Pero puede lograr un efecto similar especificando argumentos opcionales y de palabras clave