2013-06-27 19 views
7

Po pierwsze, wiem, że funkcja __init__() klasy w Pythonie nie może zwrócić wartości, więc niestety ta opcja jest niedostępna.Python __init__ return failure to create

Ze względu na strukturę mojego kodu, sensowne jest posiadanie twierdzeń danych (i monitów o podanie informacji przez użytkownika) w ramach funkcji __init__ klasy. Oznacza to jednak, że tworzenie obiektu może się nie powieść, i chciałbym móc z tego w pełni odzyskać sprawność.

Zastanawiam się, jaki jest najlepszy sposób na kontynuowanie tego. Rozważałem ustawienie globalnej wartości boolowskiej jako flagi "prawidłowej konstrukcji", ale wolałbym tego nie robić.

Jakieś inne pomysły (poza restrukturyzacją tak twierdzeń może się zdarzyć poza inicjalizacją, a wartości są przekazywane jako argumenty)? Po prostu szukam sposobu, aby powrócić 0 w przypadku powodzenia i zwrócić -1 w przypadku niepowodzenia podczas inicjalizacji. (Podobnie jak większość wywołań systemu C)

+8

Podnieś wyjątek. –

+1

Powracanie 0 w przypadku sukcesu i -1 w przypadku niepowodzenia jest bardzo un-Pythoniczne. Błędy zwracane są złe, ponieważ są łatwe do zignorowania i bardzo szczegółowe w obsłudze. Co więcej, użycie wartości 0 i -1 jako wartości logicznych powoduje tylko zamieszanie bez żadnych korzyści. Nie należy używać Pythona do pisania kodu C. – abarnert

+0

Jak wskazuje @jsbueno w swojej odpowiedzi, instancje klasy są _initialized_ w '__init __()', nie zostały utworzone, dlatego też 'nie zwraca' wartości. Zamiast używać zmiennej globalnej do wykrywania niepowodzeń, wykonując to lub wyrzucając wyjątek, możesz dodać element danych do swojej klasy, aby wskazać jego stan, a następnie bezpośrednio sprawdzić jego wartość lub wywołać metodę, która zwraca jego wartość po tym, jak '__init __()' ma został wezwany do ustalenia, czy cokolwiek (i ewentualnie co), gdy źle. – martineau

Odpowiedz

11

Można podnieść wyjątek, gdy albo assertio powiedzie, lub - jeśli naprawdę nie chce lub nie może pracować z wyjątkami, można napisać metodę __new__ w swoich klasach - w Pythonie, __init__ jest technicznie "inicjator" - i powinien wypełnić atrybuty oraz nabyć niektóre zasoby i inne, których twój obiekt będzie potrzebował w trakcie cyklu życia - Python jednak definiuje prawdziwy konstruktor, metodę __new__, która jest nazywana przed __init__ - oraz w przeciwieństwie do tego, __new__ faktycznie zwraca wartość: nowo utworzona (niezainicjowana) sama instancja.

Tak więc możesz umieścić swoje kontrole wewnątrz __new__ i po prostu zwrócić Brak jest coś, co coś nie powiedzie się - w przeciwnym razie, zwróć wynik połączenia do metody nadklasy __new__ (nie można zrobić rzeczywistej alokacji pamięci dla obiektu w czystym Pythonie , więc ostatecznie trzeba wywołać konstruktora napisany w natywnego kodu w nadrzędnej - zwykle jest to object.__new__ w bazie hierarchii klasowej

NB. w Pythonie 2, trzeba mieć object jako klasy bazowej dla Twoja hierarchia - w przeciwnym razie nie tylko __new__ nie zostanie wywołana, ponieważ wiele funkcji dodanych później do obiektów Pythona po prostu nie zadziała. class MyClass(object):, nigdy class MyClass: - chyba że jesteś na Pythonie3.

+0

Mówisz '__new__' jest wywoływana przed' __init__'. Właśnie próbowałem tego, ale '__new__' NIE jest wywoływany, gdy tworzę instancję klasy (Py2.7). –

+0

Znalazłem to. Musisz rozszerzyć obiekt na swoją klasę. Bez tego nowe nie będą wywoływane! –

+0

Nie. Jeśli pominę obiekt klasy bazowej, '__new__' nie zostanie wywołane automatycznie. Domyśl! –

0

Czy rozważałeś zgłoszenie wyjątku? To jest zwykły sposób sygnalizowania awarii.