47 votes

Comportement très étrange de l'opérateur 'est' avec des méthodes

Pourquoi le premier résultat est False , ne devrait-il pas être True ?

 >>> from collections import OrderedDict
>>> OrderedDict.__repr__ is OrderedDict.__repr__
False
>>> dict.__repr__ is dict.__repr__
True
 

56voto

Martijn Pieters Points 271458

Pour les fonctions définies par l'utilisateur, en Python 2 indépendant et lié méthodes sont créés sur demande, par le descripteur de protocole; OrderedDict.__repr__ est une méthode de l'objet, comme le enveloppés fonction est implémentée comme une pure fonction Python.

Le descripteur de protocole va appeler l' __get__ méthode sur les objets qui le prennent en charge, de sorte __repr__.__get__() est appelé chaque fois que vous essayez d'accéder OrderedDict.__repr__; pour les classes None (pas d'exemple) et la classe de l'objet lui-même qui sont transférés. Parce que vous obtenez une nouvelle méthode d'objet à chaque fois que la fonction __get__ méthode est appelée, is d'échec. Ce n'est pas la même méthode de l'objet.

dict.__repr__ n'est pas un custom Python une fonction, mais une fonction C, et de ses __get__ descripteur méthode essentiellement juste les retours self lors de l'accès à la classe. Accéder à l'attribut vous donne le même objet, à chaque fois, is fonctionne:

>>> dict.__repr__.__get__(None, dict) is dict.__repr__  # None means no instance
True

Les méthodes ont un __func__ attribut référençant le enveloppés de fonction, utiliser que pour tester l'identité:

>>> OrderedDict.__repr__
<unbound method OrderedDict.__repr__>
>>> OrderedDict.__repr__.__func__
<function __repr__ at 0x102c2f1b8>
>>> OrderedDict.__repr__.__func__.__get__(None, OrderedDict)
<unbound method OrderedDict.__repr__>
>>> OrderedDict.__repr__.__func__ is OrderedDict.__repr__.__func__
True

Python 3 n'loin avec unbound méthodes, function.__get__(None, classobj) renvoie la fonction de l'objet lui-même (il se comporte comme dict.__repr__ t). Mais vous verrez le même comportement avec bound méthodes, les méthodes récupérées à partir d'un exemple.

1voto

smesseim Points 39

Les deux OrderedDict.__repr__ ne sont pas liés au même objet. Si tu essayes:

  OrderedDict.__repr__ == OrderedDict.__repr__
 

vous verrez qu'ils ont la même valeur.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X