2012-01-04 4 views
4

Je ne comprends pas comment sont Ellipsis et None traités différemment par bool(), lorsque les deux semblent être identiques en termes d'attributs pertinents pour les tests de la vérité.Python bool (Ellipsis) et bool (Aucun)

>>> bool(Ellipsis) 
True 
>>> bool(None) 
False 
>>> any([hasattr(Ellipsis, attr) for attr in ['__len__', '__bool__', '__nonzero__']]) 
False 
>>> any([hasattr(None, attr) for attr in ['__len__', '__bool__', '__nonzero__']]) 
False 
  1. Y at-il quelque chose d'autre que je suis absent qui est utilisé pour les essais de vérité?

  2. Y a-t-il d'autres objets (en plus None) qui évaluent à False qui mettent en œuvre ni de __len__ ou __nonzero__?

Répondre

8

bool(x) est True si x est un objet sans l'une des méthodes magiques que vous avez mentionné le retour False. C'est pourquoi Ellipsis évalue à True.

None est special-cased dans bool() et le fait retourner False.

Détails:

bool() utilise la fonction API PyObject_IsTrue() qui 2.7.2 ressemble à ceci:

int 
PyObject_IsTrue(PyObject *v) 
{ 
    Py_ssize_t res; 
    if (v == Py_True) 
     return 1; 
    if (v == Py_False) 
     return 0; 
    if (v == Py_None) 
     return 0; 
    else if (v->ob_type->tp_as_number != NULL && 
      v->ob_type->tp_as_number->nb_nonzero != NULL) 
     res = (*v->ob_type->tp_as_number->nb_nonzero)(v); 
    else if (v->ob_type->tp_as_mapping != NULL && 
      v->ob_type->tp_as_mapping->mp_length != NULL) 
     res = (*v->ob_type->tp_as_mapping->mp_length)(v); 
    else if (v->ob_type->tp_as_sequence != NULL && 
      v->ob_type->tp_as_sequence->sq_length != NULL) 
     res = (*v->ob_type->tp_as_sequence->sq_length)(v); 
    else 
     return 1; 
    /* if it is negative, it should be either -1 or -2 */ 
    return (res > 0) ? 1 : Py_SAFE_DOWNCAST(res, Py_ssize_t, int); 
} 
+1

+1 pour obéir à la maxime intemporelle d'Obi-Wan: "Lire la source, Luke". Voir aussi [la documentation python sur le test de la valeur de vérité] (http://docs.python.org/py3k/library/stdtypes.html#truth-value-testing) – srgerg

+0

@wim J'ai des sources Python sur ma machine locale donc je cherche juste à travers ça. Je n'utilise pas ipython donc je ne sais pas s'il peut rechercher les sources C. – yak

+0

@srgerg Merci. J'ai ajouté le lien à la réponse. – yak

1

De l'Python data model:

Si une classe ne définit ni len() ni non nzero(), toutes ses instances sont considérées comme vraies.

NoneNone est évalué à false car il s'agit d'un type intégré specified to do so. Vous n'avez pas défini __len__() ou __nonzero__() sur Ellipsis, comme vous l'avez indiqué. Si vous voulez que l'évaluation soit fausse,

class Ellipsis(...): 
    #... 
    def __nonzero__(self): 
     return False 

    # or 
    def __len__(self): 
     return 0