Re 1, è in effetti il comportamento che abbiamo progettato - giusto o sbagliato come può essere (scusate se che i viaggi vostro caso d'uso, ma stavamo cercando di essere generale!).
In particolare, è stato a lungo il caso che ogni oggetto Python potesse essere soggetto a un confronto di disuguaglianza con tutti gli altri - oggetti di tipi che non sono realmente confronta vengono confrontati in modo arbitrario (coerentemente in una determinata esecuzione, non necessariamente attraverso le esecuzioni) ; il caso d'uso principale era l'ordinamento di un elenco eterogeneo per raggruppare gli elementi in esso per tipo.
Un'eccezione è stato introdotto solo per i numeri complessi, rendendoli non paragonabile a qualsiasi cosa - ma che era ancora molti anni fa, quando eravamo a volte cavalier di rompere perfettamente buon codice utente. Al giorno d'oggi siamo molto più restrittivi sulla compatibilità con le versioni precedenti all'interno di una major release (ad es.lungo la linea 2.*
, e separatamente lungo il 3.*
uno, anche se le incompatibilità sono ammessi tra il 2 e 3 -, infatti, che è il punto di avere una serie 3.*
, lasciando noi correggere decisioni di progettazione del passato, anche in modi incompatibili).
I confronti arbitrari si sono rivelati più problematici di quanto valgano, causando confusione all'utente; e il raggruppamento per tipo può ora essere ottenuto facilmente ad es. con argomento key=lambda x: str(type(x))
su sort
; così in Python 3 confronti tra oggetti di tipo diverso, a meno che gli oggetti stessi specificamente permettere che nei metodi di confronto, fa sollevare un'eccezione:
>>> decimal.Decimal('2.0') > 1.2
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unorderable types: Decimal() > float()
In altre parole, in Python 3 questo si comporta esattamente come si pensa che dovrebbe ; ma in Python 2 non lo fa (e mai lo sarà in nessun Python 2.*
).
Re 2, starai bene, tuttavia, guarda a gmpy per quello che spero sia un modo interessante per convertire i doppi in frazioni di precisione infinita attraverso gli alberi Farey. Se i prezzi hai a che fare con sono precisi a non più di centesimi, utilizzare '%.2f' % x
piuttosto che repr(x)
-!)
Piuttosto che una sottoclasse di decimale, mi piacerebbe utilizzare una funzione di fabbrica, come
def to_decimal(float_price):
return decimal.Decimal('%.2f' % float_price)
poiché, una volta prodotto, il decimale risultante è perfettamente ordinario.
Questa risposta è un po 'datata: 'decimal.Decimal' e' float' sono numericamente comparabili in 2.7. "Modificato nella versione 2.7: un confronto tra un'istanza float x e un'istanza Decimal y ora restituisce un risultato basato sui valori di x e y. Nelle versioni precedenti x