2010-03-11 19 views
5

Esto tiene cierta relación con mi pregunta Why is ''>0 True in Python?¿Por qué Decimal ('0')> 9999.0 es verdadero en Python?

En Python 2.6.4:

>> Decimal('0') > 9999.0 
True 

Desde el answer a mi pregunta original entiendo que al comparar objetos de diferentes tipos en Python 2.x los tipos están ordenados por su nombre. Pero en este caso:

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

¿Por qué entonces Decimal('0') > 9999.0 == True?

ACTUALIZACIÓN: suelo trabajar en Ubuntu (Linux 2.6.31-20-generiC# 57-Ubuntu SMP Lun Feb 8 09:05:19 UTC 2010 i686 GNU/Linux, Python 2.6.4 (r264: 75706, Dic 7 2009, 18:45:15) [GCC 4.4.1] en linux2). En Windows (WinXP Professional Service Pack 3, Python 2.6.4 (R264: 75706 3 Nov 2009, 13:23:17) [32 bits MSC v.1500 (Intel)] en win32) mi declaración original funciona de forma diferente:

>> Decimal('0') > 9999.0 
False 

Aún más desconcertado ahora. % - (

+0

No obtengo los mismos resultados para su primera declaración. En el mío, aparece como falso. Sin embargo, obtengo el mismo resultado para su segunda declaración. También estoy usando Python 2.6.4. –

+0

@Justin que me deja aún más perplejo ya que comprobé tres veces y devuelve 'True' – parxier

+0

usando Python 3.1.1, la primera instrucción da (después de importar el decimal):' TypeError: tipos no ordenables: Decimal()> float() ' –

Respuesta

12

Porque el módulo decimal no se compara con ningún tipo, excepto long, int y Decimal. En todos los demás casos, decimal devuelve silenciosamente "not something about object" como mayor. Puede ver este comportamiento . en la función _convert_other() de decimal.py

tonto, tonto clase decimal

Oh, ver http://bugs.python.org/issue2531 así

por lo tanto, esto es lo que sucede:.

  • El intérprete llama a la función de comparación Decimal.__gt__.
  • Decimal.__gt__ llama al Decimal._convert_other para convertir el flotador entrante en un decimal.
  • Decimal._convert_other no entiende las carrozas. La implementación hacia abajo en Decimal._convert_other comprueba explícitamente para long, int y Decimal tipos del operando. Sí, esto es un error, en el que las implementaciones inesperadas de la biblioteca causan errores más adelante en la línea. Es sería más limpio para hacer lo correcto o incluso solo a través de TypeException. En su lugar, pasa por el mismo NotImplemented que sucedería al comparar un decimal con, por ejemplo, un hash de registros de empleados.
  • Se intentan algunas otras operaciones de comparación. La comparación se rinde.
  • Se llama a la comparación predeterminada, abajo en objetos/object.c/default_3way_compare de CPython.
  • En Python 3, este derecho barfs. En Python 2, compara las funciones id().
  • En Windows, se usa una comparación insensible a mayúsculas y minúsculas (más o menos). En sistemas modernos, se usa una comparación sensible a mayúsculas .
  • Para obtener resultados diferentes.

¿Ya llegamos?

+0

Tx por hacerme las cosas bien, así que borré mi respuesta (engañosa) y hice +1 en agradecimiento al tuyo ;-). –

+0

@charles: ¿Por qué funciona de manera diferente en diferentes plataformas? – parxier

+0

No hay pista. No tengo Windows. Intenta jalar el _convert_other() en ambos y compararlos. –

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 
Cuestiones relacionadas