2010-10-05 12 views
22

Quiero configurar una clase que se cancelará durante la creación de la instancia en función del valor del argumento pasado a la clase. He intentado un par de cosas, una de ellas es elevar un error en el método __new__:¿Cómo cancelo la creación de instancia de objeto en Python?

class a(): 
    def __new__(cls, x): 
     if x == True: 
      return cls 
     else: 
      raise ValueError 

Esto es lo que estaba esperando que sucedería:

>>obj1 = a(True) 
>>obj2 = a(False) 
ValueError Traceback (most recent call last) 

obj1 existe, pero no lo hace obj2 .

¿Alguna idea?

+0

¿no debería usted anular '__init __ (self, ...)'? –

+0

@matt b. No es tan semántico si la intención es detener la creación de objetos. Sin embargo funciona. – aaronasterling

+0

@AaronMcSmooth: ¿Por qué sería preferible plantear una excepción en '__new__' que plantear una en' __init__'. El resultado me parece igual y '__init__' es donde va el resto del código de inicialización. ¿Por qué no debería ir esto también? – Arlaharen

Respuesta

16

Cuando se reemplaza __new__, no se olvide de llamar a super!

>>> class Test(object): 
...  def __new__(cls, x): 
...   if x: 
...    return super(Test, cls).__new__(cls) 
...   else: 
...    raise ValueError 
... 
>>> obj1 = Test(True) 
>>> obj2 = Test(False) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "<stdin>", line 6, in __new__ 
ValueError 
>>> obj1 
<__main__.Test object at 0xb7738b2c> 
>>> obj2 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
NameError: name 'obj2' is not defined 

Simplemente volviendo a la clase no hace nada cuando era su trabajo para crear una instancia. Esto es lo que hace el método de la superclase __new__, así que aprovéchelo.

+0

Si también necesito una variable x, ¿qué debo hacer? – mertyildiran

3

Sólo levanta una excepción en el inicializador:

class a(object): 
    def __init__(self, x): 
     if not x: 
      raise Exception() 
+1

'__init__' no es el constructor, es el inicializador. Estás pensando en '__new__' – Daenyth

Cuestiones relacionadas