2010-07-06 19 views
5

Mi piacerebbe essere in grado di far interagire l'operatore della mia classe con i tipi regolari in un modo che definisco. Diciamo, per esempio, ho:Python: Operatore Sovraccarico di un tipo specifico

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 

Questo funziona bene, ma ora se cerco di fare:

print a+2 

ottengo un errore poiché un int non ha un membro nominato x . Come definisco Mynum + int nella classe? Sembra un lavoro per decoratori o metaclassi, ma sono terribilmente poco familiare con il loro utilizzo. This question sembra simile, ma non del tutto identico.

+0

controllare il tipo o "altro" o presenza di attributo 'x'. – SilentGhost

+0

non dimenticarti di fare: '__radd__' =' __add__' anche (anche se non risolve il tuo problema) – jcao219

risposta

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

Grazie, non ho mai visto 'isinstance' prima. Questo è considerato il modo corretto per farlo, o dovrei usare il blocco try/except proposto da unutbu? – Hooked

+0

La clausola 'try ... except' è veloce quando non viene sollevata alcuna eccezione e rallenta altrimenti. Pertanto, è possibile utilizzarlo se l'aggiunta di due istanze della classe è l'uso più comune dell'aggiunta sovraccaricata. Altrimenti, l'approccio "insinstance" è buono. – EOL

+0

Non dovresti restituire "NotImplemented" invece di aumentare ed eccezionarti? – 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

Perché usare la commutazione extra e/o la gestione delle eccezioni? Utilizzare il seguente sarebbe un approccio più semplice:

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 
Problemi correlati