2010-10-05 15 views
22

Chcę ustawić klasę, która zostanie przerwana podczas tworzenia instancji na podstawie wartości argumentu przekazanego do klasy. Próbowałem kilka rzeczy, jedną z nich jest podnoszenie błąd w metodzie __new__:Jak przerwać tworzenie instancji obiektu w Pythonie?

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

To jest to, czego oczekiwałem by się stało:

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

obj1 istnieje, ale nie obj2 .

Wszelkie pomysły?

+0

nie powinieneś zastąpić '__init __ (self, ...)' zamiast? –

+0

@matt b. Nie jest to tak semantyczne, jeśli następnie intencją jest zatrzymanie tworzenia obiektów. To działa. – aaronasterling

+0

@AaronMcSmooth: Dlaczego podniesienie wyjątku w '__new__' byłoby lepsze niż podniesienie wyjątku w' __init__'. Rezultat wydaje mi się taki sam, a "__init__" to miejsce, w którym znajduje się cały inny kod inicjalizacyjny. Dlaczego nie powinieneś tam pojechać? – Arlaharen

Odpowiedz

16

Kiedy zastąpić __new__, nie zapomnij zadzwonić do 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 

Wystarczy powrocie klasę nic nie robi, gdy było zadanie utworzyć instancję. Tak właśnie działa metoda klasy super-klasy __new__, więc wykorzystaj ją.

+0

Jeśli potrzebuję również zmiennej x, co powinienem zrobić? – mertyildiran

3

Wystarczy podnieść wyjątek w inicjalizatorze:

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

'__init__' nie jest konstruktorem, jest inicjatorem. Myślisz o '_new__' – Daenyth

Powiązane problemy