2012-01-22 8 views
17
Python 2.7.2 (default, Jun 12 2011, 14:24:46) [MSC v.1500 64 bit (AMD64)] on win32 
Type "help", "copyright", "credits" or "license" for more information. 
>>> None > 0 
False 
>>> None == 0 
False 
>>> None < 0 
True 
  • está comparando None utilizando operadores aritméticos bien definidos para los tipos integrados (enteros, en este caso)?
  • ¿La diferencia entre las dos primeras y la tercera parte de comparación de la especificación del lenguaje (especificación de Python - debe estar bromeando :)) o es el detalle de implementación de CPython?
+4

'==' y '! =' Suelen ser seguros, pero que se supone que es usar '' None' y no es para None' únicos como 'None' según [PEP-8] (http://www.python.org/dev/peps/pep-0008/) – ThiefMaster

+2

@ThiefMaster El objetivo de la pregunta es qué significa * safe * aquí. Soy consciente de que uno debe usar 'is' para comparar con' None' pero la pregunta es específica y no pregunta sobre qué operador se debe usar. –

+0

http://bugs.python.org/issue1673405 – wim

Respuesta

17

La única comparación significativa que realmente se puede utilizar con None es if obj is None: (o if obj is not None:).

La comparación entre diferentes tipos se ha eliminado de Python 3 por buenas razones: eran una fuente común de errores y generaban confusión. Por ejemplo

>>> "3" < 4 
False 

En Python 3, se obtiene una TypeError al comparar los valores de diferentes tipos como str vs int o nada frente a None.

>>> None < 0 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: unorderable types: NoneType() < int() 

(me refiero a "comparar" en el sentido de tratar de determinar cuál de los dos valores es mayor/menor Comparación de la igualdad está bien -. Siempre devolverá False si dos objetos son de diferentes tipos.)

no he encontrado una referencia en la documentación para esto, pero en Learning Python, 4th edition, Marcos Lutz escribe en la página 204:

[...] Comparisons of differently typed objects (e.g., a string and a list) work — the language defines a fixed ordering among different types, which is deterministic, if not aesthetically pleasing. That is, the ordering is based on the names of the types involved: all integers are less than all strings, for example, because "int" is less than "str" .

+0

¿Hay alguna información en los documentos sobre esto? –

+1

¿Cuál es la razón técnica por la cual 'None <0' es verdadero? – wim

+4

@wim: 'None' es el" tipo más bajo "en Python 2, por lo que' None' siempre es más bajo que cualquier 'int' que siempre es más bajo que cualquier' str' etc. –

4

Algunas citas interesantes de http://bytes.com/topic/python/answers/801701-why-none-0-a

In early Python, the decision was made that the comparison of any two objects was legal and would return a consistent result. So objects of different types will compare according to an ordering on their types (an implementation dependent, unspecified, but consistent ordering), and objects of the same type will be compared according to rules that make sense for that type.

Other implementations have the right to compare an integer and None differently, but on a specific implementation, the result will not change.

Python 3 will raise an exception on such comparisons.

y

The problem is the typical one; Python did not originally have a Boolean type, and the retrofit resulted in weird semantics. C has the same issue.

+0

Esto es realmente enfermo. Otra razón para evitar Python 3 el mayor tiempo posible. Por lo tanto, no puede ordenar una lista de objetos heterogéneos a partir de ahora ... '>>> ordenado ([2, 1.5, 2.5]) [1.5, 2, 2.5] >>> clasificado ([2, 1.5, 2.5, 'bla', '2', '2.5', Ninguno]) Traza (última llamada más reciente): Archivo "", línea 1, en TypeError: tipos no pedidos: str()

+6

Argumentaría eso como una razón para _prefer_ python 3 .. ¿Cuál es el resultado esperado de 'sorted ([2, 1.5, 2.5, 'bla', '2', '2.5', None])'? – moveaway00

Cuestiones relacionadas