2010-03-22 22 views
68

Tengo una clase con una función __init__.¿Cómo devolver un valor desde __init__ en Python?

¿Cómo puedo devolver un valor entero desde esta función cuando se crea un objeto?

Escribí un programa, donde __init__ realiza un análisis de línea de comandos y necesito que se establezca algún valor. ¿Está bien configurarlo en variable global y usarlo en otras funciones miembro? Si es así, ¿cómo hacer eso? Hasta ahora, he declarado una variable fuera de clase. y establecerlo una función no se refleja en otra función?

+6

Si estaba considerando devolver un código de error, haga una excepción. –

+0

Por favor, elimine su comentario y actualice su pregunta. Usted es el propietario de la pregunta. Es tu pregunta Por favor, corrija la pregunta para mostrar correctamente cuál es su problema real. Estás mal usando '__init__'; podemos ayudarte si describes lo que realmente estás tratando de lograr. –

Respuesta

67

__init__ es necesario para devolver Ninguno. No puede (o al menos no debería) devolver algo más.

Intente hacer lo que quiera devolver una variable de instancia (o función).

>>> class Foo: 
...  def __init__(self): 
...   return 42 
... 
>>> foo = Foo() 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: __init__() should return None 
+15

+1: ** No puedes devolver algo más **. No tiene ningún sentido. –

+63

__init__ no devuelve el objeto recién creado: como se ve en TypeError, se requiere que devuelva None, ¿no? El objeto recién creado es devuelto por __new__, __init__ solo establece algunos de sus atributos. Pero sí, como dijiste, cambiar __init__, o __new__, para devolver algo más realmente no tiene sentido. – weronika

+0

¿Dónde está 'nuevo' aquí? ¿Está 'nuevo' implícito en Python? Supuse que la semántica de Python era diferente de Java y de los otros lenguajes que usan esta palabra. –

8

__init__ no devuelve nada y siempre debe volver None.

37

Desde el documentation of __init__:

As a special constraint on constructors, no value may be returned; doing so will cause a TypeError to be raised at runtime.

Como prueba, este código:

class Foo(object): 
    def __init__(self): 
     return 2 

f = Foo() 

da este error:

Traceback (most recent call last): 
    File "test_init.py", line 5, in <module> 
    f = Foo() 
TypeError: __init__() should return None, not 'int' 
85

¿Por qué querrías hacer eso?

Si desea devolver algún otro objeto cuando una clase se llama, a continuación, utilizar el __new__() método:

class MyClass(object): 
    def __init__(self): 
     print "never called in this case" 
    def __new__(cls): 
     return 42 

obj = MyClass() 
print obj 
+8

Sí, __new__ es la forma correcta de devolver algo que no sea una instancia de clase cuando utilizo una clase ... Me pregunto: ¿hay alguna razón por la que realmente desee HACER eso? – weronika

+22

@weronika Una idea: en cualquier situación en la que normalmente usaría una fábrica, pero tiene algún motivo para querer presentar una interfaz que se parece a la instanciación de clase normal. Ejemplo: al agregar algunos nuevos parámetros opcionales en el '__init__' de su clase, se da cuenta de que realmente, para proporcionar la flexibilidad que desea, necesita una fábrica de clases que devuelva instancias de subclases especializadas. Pero los usuarios de su biblioteca ya están usando su API existente. Para preservarlo, anula '__new__' para devolver instancias de sus subclases especializadas. –

+6

Si desea ver un ejemplo de lo que dijo Mark Amery, consulte el código fuente del módulo 'datetime' de la Biblioteca estándar. Utiliza '__new__' exactamente de esta manera. – Zearin

12

El método __init__, al igual que otros métodos y funciones devuelve Ninguno de forma predeterminada en la ausencia de un retorno declaración, por lo que se puede escribir como cualquiera de los siguientes:

class Foo: 
    def __init__(self): 
     self.value=42 

class Bar: 
    def __init__(self): 
     self.value=42 
     return None 

Pero, por supuesto, la adición de la return None no te comprar nada.

no estoy seguro de lo que está después, pero que podría estar interesado en uno de estos:

class Foo: 
    def __init__(self): 
     self.value=42 
    def __str__(self): 
     return str(self.value) 

f=Foo() 
print f.value 
print f 

impresiones:

Uso
42 
42 
+0

ohh ... ¿Puedo acceder a la variable miembro de la clase? Entonces eso debería resolver mi problema ... gracias –

+0

@lakshmipathi, Sí, las variables de instancia como esta son públicas. – quamrana

+0

Como un delineador para obtener algo valioso devuelto después del inicio de una clase: 'f = Foo(). Value' – JLT

13

muestra de la materia en cuestión puede ser como :

class SampleObject(object) 

    def __new__(cls,Item) 
     if self.IsValid(Item): 
      return super(SampleObject, cls).__new__(cls) 
     else: 
      return None 

    def __init__(self,Item) 
     self.InitData(Item) #large amount of data and very complex calculations 

... 

ValidObjects=[] 
for i in data: 
    Item=SampleObject(i) 
    if Item:    # in case the i data is valid for the sample object 
     ValidObjects.Append(Item) 

no tengo la reputación suficiente, así que no puedo escribir un comentario, que me está loco!Me gustaría poder publicar como un comentario a weronika

+1

Esto levantará un NameError: 'self' no está definido en' __new__ (cls, Item) ' –

2

Sólo quería añadir clases, puede regresar en __init__

@property 
def failureException(self): 
    class MyCustomException(AssertionError): 
     def __init__(self_, *args, **kwargs): 
      *** Your code here *** 
      return super().__init__(*args, **kwargs) 

    MyCustomException.__name__ = AssertionError.__name__ 
    return MyCustomException 

El método anterior le ayuda a implementar un proceso cuando una excepción en su prueba

+0

por favor, elabore este código. – nish

Cuestiones relacionadas