2010-03-11 15 views
5

ta jest w jakiś sposób związane z moim pytaniem Why is ''>0 True in Python?Dlaczego jest dziesiętny ("0")> 9999.0 Prawda w python?

W Pythonie 2.6.4:

>> Decimal('0') > 9999.0 
True 

Z answer do mojego pierwotnego pytania rozumiem, że przy porównywaniu obiektów różnych typów w Pythonie 2.x typy są zamawiane według ich nazwy. Ale w tym przypadku:

>> type(Decimal('0')).__name__ > type(9999.0).__name__ 
False 

Dlaczego zatem Decimal('0') > 9999.0 == True?

AKTUALIZACJA: Zwykle pracuję na systemie Ubuntu (Linux 2.6.31-20-generiC# 57-Ubuntu SMP Pon 8 lutego 09:05:19 UTC 2010 i686 GNU/Linux, Python 2.6.4 (r264: 75706, Dec 7 2009, 18:45:15) [GCC 4.4.1] na Linux2). W systemie Windows (WinXP Professional SP3, Python 2.6.4 (r264: 75706, 3 listopada 2009, 13:23:17) [MSC v.1500 32 bit (Intel)] na win32) moje oryginalne polecenie działa inaczej:

>> Decimal('0') > 9999.0 
False 

Jeszcze bardziej zdziwiłem się. % - (

+0

Nie otrzymuję takich samych wyników dla pierwszego wyciągu. Na moim pojawia się jako Fałsz. Mimo to otrzymuję taki sam wynik dla twojego drugiego stwierdzenia. Używam również Python 2.6.4. –

+0

@Justin, które pozostawia mnie jeszcze bardziej zaintrygowany, jak potrójne sprawdzane i zwraca 'True' – parxier

+0

przy użyciu Pythona 3.1.1, pierwsza instrukcja podaje (po zaimportowaniu dziesiętnych):' TypeError: unorderable types: Decimal()> float() ' –

Odpowiedz

12

Ponieważ moduł dziesiętny nie porównuje żadnego typu oprócz długiego, int i dziesiętnego, we wszystkich innych przypadkach wartość dziesiętna po cichu zwraca "nie coś, co wie o obiekcie" jako większe. . w funkcji _convert_other() z decimal.py

głupie, głupie klasy dziesiętny

Och, patrz http://bugs.python.org/issue2531 oraz

tak, o to, co się dzieje.

  • Interpreter wywołuje funkcję porównania Decimal.__gt__.
  • Decimal.__gt__ dzwoni pod numer Decimal._convert_other, aby przekonwertować przychodzący float na dziesiętny.
  • Decimal._convert_other nie rozumie pływaków. Implementacja w dół w Decimal._convert_other jawnie sprawdza dla typów operandu long, int i Decimal. Tak, to jest błąd, ponieważ nieoczekiwane implementacje bibliotek powodują błędy w dalszej linii. To byłoby czystsze, aby zrobić dobrą rzecz, a nawet po prostu przez TypeException. Zamiast tego przechodzi przez to samo NotImplemented, co mogłoby się zdarzyć, porównując dziesiętny do, powiedzmy, mieszania rekordów pracowników.
  • Próbowano wykonać kilka innych operacji porównania. Porównanie się poddaje.
  • Wywoływane jest domyślne porównanie w CPython's Objects/object.c/default_3way_compare.
  • W Pythonie 3, to słusznie barfuje. W Pythonie 2 porównuje funkcje id().
  • W systemie Windows używane jest sortowanie niewrażliwe na wielkość liter (sortowanie). W nowoczesnych systemach używane jest rozróżnianie wielkości liter w przypadku rozróżniania wielkości liter.
  • Otrzymujesz różne wyniki.

Jesteśmy tam jeszcze?

+0

Tx za ustawienie mnie w prawo, więc usunąłem moją (wprowadzającą w błąd) odpowiedź, a + 1-kę z wdzięczności ;-). –

+0

@charles: dlaczego to działa inaczej na różnych platformach? – parxier

+0

Nie ma pojęcia. Nie mam systemu Windows. Spróbuj wyciągnąć _convert_other() na obu i porównać je. –

1
def __gt__(self, other, context=None): 
    other = _convert_other(other) 
    if other is NotImplemented: 
     return other 
    ans = self._compare_check_nans(other, context) 
    if ans: 
     return False 
    return self._cmp(other) > 0 


def _convert_other(other, raiseit=False): 
    """Convert other to Decimal. 

    Verifies that it's ok to use in an implicit construction. 
    """ 
    if isinstance(other, Decimal): 
     return other 
    if isinstance(other, (int, long)): 
     return Decimal(other) 
    if raiseit: 
     raise TypeError("Unable to convert %s to Decimal" % other) 
    return NotImplemented