2010-05-05 6 views
0

Je suis encore 99 +% en utilisant python 2.x, mais j'essaie de penser au jour où je passerai. Donc, je sais que l'utilisation d'opérateurs de comparaison (moins/plus grand ou égal à) sur les types hétérogènes qui n'ont pas d'ordre naturel n'est plus supportée dans python3.x - au lieu de certains cohérente (mais arbitraire) résultat nous élevons TypeError à la place. Je vois la logique dans cela, et même la plupart du temps pense que c'est une bonne chose. La cohérence et le refus de deviner est une vertu.comparaisons hétérogènes dans python3

Mais qu'en est-il si vous voulez essentiellement le comportement de python2.x? Quelle est la meilleure façon de l'obtenir? Pour le plaisir (plus ou moins), j'ai récemment mis en œuvre une Skip List, une structure de données qui garde ses éléments triés. Je voulais utiliser des types hétérogènes comme des clés dans la structure de données, et je dois comparer les clés les unes aux autres lorsque je marche sur la structure de données. La façon de comparer python2.x est très pratique - vous obtenez un ordre compréhensible parmi les éléments qui ont un ordre naturel, et certains ordonnant parmi ceux qui ne le font pas.

L'utilisation constante d'une clé de tri/comparaison telle que (type(obj).__name__, obj) présente l'inconvénient de ne pas entrelacer les objets qui ont un ordre naturel; vous obtenez tous vos float s regroupés avant vos int s, et votre classe str se sépare de vos str s.

je suis venu avec ce qui suit:

import operator 

def hetero_sort_key(obj): 
    cls = type(obj) 
    return (cls.__name__+'_'+cls.__module__, obj) 

def make_hetero_comparitor(fn): 
    def comparator(a, b): 
     try: 
      return fn(a, b) 
     except TypeError: 
      return fn(hetero_sort_key(a), hetero_sort_key(b)) 
    return comparator 

hetero_lt = make_hetero_comparitor(operator.lt) 
hetero_gt = make_hetero_comparitor(operator.gt) 
hetero_le = make_hetero_comparitor(operator.le) 
hetero_ge = make_hetero_comparitor(operator.gt) 

Y at-il une meilleure façon? Je suppose que l'on pourrait construire un boîtier d'angle que ce serait bousiller - une situation où vous pouvez comparer le type A à B et le type A à C, mais où B et C augmentent TypeError par rapport, et vous pouvez finir avec quelque chose d'illogique comme a > b, a < c, et pourtant b > c (en raison de la façon dont leurs noms de classe triés). Je ne sais pas quelle est la probabilité que vous rencontriez cela en pratique.

Répondre

0

Plutôt que de "réparer" quelque chose que la communauté python 3.x a "corrigé" dans la portée globale, vous pouvez tenter l'approche permettant à vos objets/types de trier correctement. Je ne suis pas aussi familier avec python 3.x, mais je suis sûr qu'il y a toujours une méthode __cmp__ que vous pouvez remplacer dans une sous-classe et corriger afin que les comparaisons fonctionnent. Vous pouvez utiliser cela en combinaison avec id() pour restaurer l'ancien comportement brisé (qui vient de trier en fonction de la position en mémoire, id(), si ma mémoire me sert correctement).