委托添加到自定义类的就地添加是一个好主意吗?

时间:2017-10-03 09:28:36

标签: python oop operator-overloading

鉴于需要支持添加的自定义类,是否有任何理由不将__add__方法委派给__iadd__,以便:

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 

除了copy.deepcopy可能是记忆问题这一事实之外,我无法想出任何事情,但因为添加应该返回一个新对象并保持self不变,我不确定是否可以避免。另一种方法是使用构造函数实例化一个新对象,如果该类有许多可变变量,那么它实际上并不是一个简洁的选项。就我而言,它是一个随机模型,它是从一大堆训练数据中生成的,因此更容易获得副本。

以上所有定义都符合要求,但我没有在任何教程中看到这两种方法之间的依赖关系,这让我有点怀疑。

这有什么危险或不好的做法吗?

1 个答案:

答案 0 :(得分:1)

这当然是C ++中自然和推荐的做事方式。

另一方面,如果您有不可变对象(如基本整数或字符串类型),则不会有__iadd__,并且必须直接实现__add__

如果您没有__iadd__,请从the docs x += y x.__add__(y)调用y.__radd__(x)var Memo1dc: hdc; Cnv: TCanvas; Rct: TRect; implementation procedure TForm1.MemoHideTimerTimer(Sender: TObject); begin if Memo1.Visible then begin Memo1dc := GetDC(Memo1.Handle); Cnv.Handle := Memo1dc; Rct.Height := Memo1.Height; Rct.Width := Memo1.Width; Image1.Left := Memo1.Left; Image1.Top := Memo1.Top; Image1.Width := Memo1.Width; Image1.Height := Memo1.Height; Image1.Canvas.CopyRect(Rct, Cnv, Rct); Memo1.Visible := False; Image1.Visible := True; end; if (hideAnimVal < 1) then begin hideAnimVal := hideAnimVal + 0.025; end else begin MemoHideTimer.Enabled := False; end; // hideStart - starting position of my TMemo, hideEnd - end position of my TMemo hideCurr := Round(CosineInterpolation(hideStart, hideEnd, hideAnimVal)); Image1.Left := hideCurr; if MemoHideTimer.Enabled = False then begin Memo1.Left := Image1.Left; Memo1.Visible := True; Image1.Visible := False; end; end; procedure TForm1.FormCreate(Sender: TObject); begin Cnv := TCanvas.Create; end; ,然后将结果分配给x。< / p>