2010-07-06 13 views
5

Ich möchte in der Lage sein, den Operator meiner Klasse mit regulären Typen in einer Weise interagieren zu lassen, die ich definiere. Sagen wir, zum Beispiel, ich habe:Python: Operator Überladen eines bestimmten Typs

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 

Das funktioniert ganz gut, aber jetzt, wenn ich versuche zu:

print a+2 

ich einen Fehler, da ein int nicht Mitglied x genannt haben . Wie definiere ich Mynum + int in der Klasse? Das hört sich nach einem Job für Dekorateure oder Metaklassen an, aber ich kenne sie nicht sehr gut. This question scheint ähnlich, aber nicht ganz identisch.

+0

Überprüfen Sie den Typ oder 'andere' oder das Vorhandensein von' x' Attribut. – SilentGhost

+0

nicht vergessen zu tun: '__radd__' =' __add_' auch (auch wenn es nicht Ihr Problem behebt) – jcao219

Antwort

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

Vielen Dank, ich habe 'isinstance' vorher noch nie gesehen. Ist dies der richtige Weg, oder sollte ich den von unutbu vorgeschlagenen try/except-Block verwenden? – Hooked

+0

Die Klausel 'try ... except' ist schnell, wenn keine Ausnahme ausgelöst wird, und andernfalls langsam. Daher können Sie es verwenden, wenn das Hinzufügen von zwei Instanzen Ihrer Klasse die häufigste Verwendung des überladenen Zusatzes ist. Ansonsten ist der Ansatz "instinstance" gut. – EOL

+0

Sollten Sie 'NotImplemented' nicht zurückgeben, anstatt sich selbst zu erhöhen und Ausnahmen zu machen? – 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

Warum nutzen die zusätzliche Schalt- und/oder Ausnahmebehandlung? Die Verwendung des Folgenden wäre ein einfacherer Ansatz:

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