2011-11-20 10 views
56

Dlaczego to nie działa tak, jak się można naiwnie spodziewać?Definiowanie "boolness" klasy w python

class Foo(object): 
    def __init__(self): 
     self.bar = 3 
    def __bool__(self): 
     return self.bar > 10 

foo = Foo() 

if foo: 
    print 'x' 
else: 
    print 'y' 

(wyjście jest x)

+0

Duplikat rozwiązuje tylko problem dla Pythona 2. Podczas gdy ten daje przenośne rozwiązanie. –

Odpowiedz

60

Dla kompatybilności Python 2-3, wystarczy dodać to do Twojego przykładu:

Foo.__nonzero__ = Foo.__bool__ 

lub rozwinąć oryginalną definicję Foo obejmuje:

__nonzero__ = __bool__ 

Można oczywiście zdefiniować je w odwrotnej kolejności też, gdzie nazwa metody to __nonzero__ i przypisujesz ją do __bool__, ale myślę, że nazwa __nonzero__ jest po prostu spuścizną oryginalnego C-ishness interpretacji obiektów Pythona jako prawdy lub falsy w oparciu o ich równoważność z ero. Wystarczy dodać powyższe oświadczenie, a kod będzie działał z Pythonem 2.x i będzie działać automatycznie po uaktualnieniu do Pythona 3.x (i ostatecznie porzucisz zadanie na __nonzero__).

+3

Podoba mi się to słowo, C-ishness – wim

+2

Jestem neologikiem. – PaulMcG

+0

i dziwna pętla. –

49

Sposób __bool__ stosuje się Pythonie 3. Do Python 2, chcesz __nonzero__.

+0

prawda, dziwne, ale prawdziwe. dobrze widzieć, że zmienili implementację na "jeden oczywisty sposób na zrobienie tego". – wim

+6

@wim: Niezbyt dziwne. Nazwa metody '__nonzero __()' znacznie wyprzedza wprowadzenie typu 'bool' w języku Python. Przed 'bool', po prostu używaj liczb całkowitych' 0' i '1'. –

+1

Tak, przeczytanie tego było dość niespodzianką. Prawda i fałsz są koncepcyjnie bardzo różne od liczb całkowitych 0 i 1, więc bardzo się cieszę, bool został wprowadzony. Wciąż uważam za dziwne, że bool jest podklasą int, i wzdrygam się, gdy widzę, że ktoś indeksuje tablicę z boolem. – wim