2010-07-06 9 views
5

Je voudrais pouvoir faire interagir l'opérateur de ma classe avec les types réguliers d'une manière que je définis. Disons, par exemple, j'ai:Python: Opérateur Surcharge d'un type spécifique

class Mynum(object): 
    def __init__(self, x): 
    self.x = x 
    def __add__(self, other): 
    return self.x + other.x 

a = Mynum(1) 
b = Mynum(2) 

print a+b 

Cela fonctionne très bien, mais maintenant si j'essaie de faire:

print a+2 

Je reçois une erreur car une int ne dispose pas d'un membre nommé x . Comment définir Mynum + int dans la classe? Cela ressemble à un travail pour les décorateurs ou les métaclasses, mais je suis terriblement peu familier avec leur utilisation. This question semble similaire, mais pas tout à fait identique.

+0

vérifier le type ou l'attribut 'autre' ou présence de' x'. – SilentGhost

+0

ne pas oublier de faire: '__radd__' =' __add__' aussi (même si cela ne résout pas votre problème) – jcao219

Répondre

11
def __add__(self, other): 
    if isinstance(other, self.__class__): 
     return self.x + other.x 
    elif isinstance(other, int): 
     return self.x + other 
    else: 
     raise TypeError("unsupported operand type(s) for +: '{}' and '{}'").format(self.__class__, type(other)) 
+0

Merci, je n'ai jamais vu 'isinstance' avant. Est-ce considéré comme le bon moyen de le faire, ou devrais-je utiliser le bloc try/except proposé par unutbu? – Hooked

+0

La clause 'try ... except' est rapide quand aucune exception n'est levée, et lente sinon. Par conséquent, vous pouvez l'utiliser si l'ajout de deux instances de votre classe est l'utilisation la plus courante de l'addition surchargée. Sinon, l'approche «insinstance» est bonne. – EOL

+0

Ne devriez-vous pas retourner 'NotImplemented' à la place de lever et d'exception vous-même? – jpcgt

4
class Mynum(object): 
    def __init__(self, x): 
     self.x = x 
    def __add__(self, other): 
     try: 
      return self.x + other.x 
     except AttributeError: 
      return self.x + other 
    __radd__=__add__ 

a = Mynum(1) 
b = Mynum(2) 

print(a+b) 
# 3 
print(a+2) 
# 3 
print(2+a) 
# 3 
2

Pourquoi utiliser la commutation supplémentaire et/ou la gestion des exceptions? L'utilisation de ce qui suit serait une approche plus simple:

class MyNum(object): 
    def __init__(self, x): 
     self.x = x 
    def __add__(self, other): 
     return other + self.x 
    __radd__ = __add__ 
x = MyNum(5) 
y = MyNum(6) 
print x + 2 
7 
print 2 + x 
7 
print x + y 
11 
print y + x 
11