2017-10-03 1 views
0

Etant donnée une classe personnalisée qui doit prendre en charge plus, y at-il des raisons de ne pas déléguer la méthode __add__-__iadd__ tel que:Est-ce une bonne idée de déléguer l'ajout à l'ajout sur place pour les classes personnalisées?

def __add__(self, other): 
    if not self.comparable(other): 
     raise ValueError("Objects cannot be added!") 

    temp = copy.deepcopy(self) 
    temp += other 
    return temp 

def __iadd__(self, other): 
    if not self.comparable(other): 
     raise ValueError("Objects cannot be added!") 

    self.x += other.x 
    self.y += other.y 
    # ... whatever else addition voodoo 

Je ne peux pas arriver à quelque chose en dehors du fait que copy.deepcopy pourrait être un problème pour mémoire, mais puisque l'addition est supposé retourner un nouvel objet et laisser self inchangé, je ne suis pas sûr qu'il peut être évité. Une alternative serait d'instancier un nouvel objet avec le constructeur, ce qui n'est pas vraiment une option soignée si la classe a beaucoup de variables mutables. Dans mon cas, il s'agit d'un modèle stochastique généré à partir d'un ensemble de données d'entraînement, il était donc plus facile d'en obtenir une copie. Dans l'ensemble, les définitions ci-dessus sont conformes aux exigences, mais je n'ai pas vu ce type de dépendance entre les deux méthodes dans un tutoriel qui me rend un peu suspect.

Est-ce dangereux ou une mauvaise pratique?

Répondre

1

C'est certainement la manière naturelle et recommandée de faire les choses en C++. D'autre part, si vous avez des objets immuables (comme les types entiers ou chaînes de base), vous n'aurez pas de __iadd__ et devrez implémenter directement __add__.

De the docs si vous ne disposez pas d'un __iadd__, x += y invoqueront soit x.__add__(y) ou y.__radd__(x) puis attribuez-lui le résultat x.