2010-10-05 24 views
22

Voglio impostare una classe che verrà interrotta durante la creazione dell'istanza in base al valore dell'argomento passato alla classe. Ho provato un paio di cose, uno dei quali è sollevare un errore nel metodo __new__:Come interrompere la creazione di istanze dell'oggetto in Python?

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

Questo è quello che speravo che sarebbe accaduto:

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

obj1 esiste, ma non lo fa obj2 .

Qualche idea?

+0

non dovresti sovrascrivere '__init __ (self, ...)'? –

+0

@matt b. Non è così semantico se poi l'intento è fermare la creazione di oggetti. Funziona comunque. – aaronasterling

+0

@AaronMcSmooth: perché alzare un'eccezione in '__new__' è preferibile aumentarne uno in' __init__'. Il risultato sembra lo stesso per me e '__init__' è dove tutto l'altro codice di inizializzazione va. Perché non dovrebbe andare anche lì? – Arlaharen

risposta

16

Quando si ignora __new__, non dimenticate di chiamare al 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 

Semplicemente tornando la classe non fa nulla quando era vostro lavoro per creare un'istanza. Questo è ciò che fa il metodo __new__ della super classe, quindi approfittane.

+0

Se ho bisogno anche di una variabile x, cosa dovrei fare? – mertyildiran

3

Basta sollevare un'eccezione nel inizializzatore:

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

'__init__' non è il costruttore, è l'inizializzatore. Stai pensando a '__new__' – Daenyth

Problemi correlati