python魔法方法: 增量運算

class A:
  a = 0
  
  def __iadd__(self, b):
    print('->', b)
    self.a += b
    
a = A()
print(a)
print(a.a)

b = a
print(b)
print(b.a)

a += 2
print(a)
print(b)
print(b.a)

在這裏插入圖片描述

增量運算(+=)時 將調用本身的__iadd__魔法方法,實際上下次使用該變量是是直接使用的增量運算函數的返回值,因此此處a的增量運算返回值爲None,而b的結果爲2

當我們迴歸其本質:x += 1 ==> x = x + 1 可以看出,x 其實進行了重新賦值,重新賦值成了 iadd 的返回值。而我們代碼示例中,這個方法的返回值是一個字符串。在一開始時,x是我們類的實例。但是在進行了增量運算後,x 變成了魔法方法的返回值,也就是字符串了,所以纔會出現以上的報錯。

所以我們在使用的時候要注意 x 身份的改變,不然會有許多意想不到的麻煩

還有一些列子:

class Foo(object):
    def __init__(self, x):
        self.x = x

    def __iadd__(self, other):
        return 'Foo iadd: %s + %s' % (self.x, other)

a = Foo(123)
a += 1
print(a)

輸出爲 Foo iadd: 123 + 1

但是,如果兩個對象的實現了__iadd__,情況就會大爲不同:

class Foo(object):
    def __init__(self, x):
        self.x = x

    def __iadd__(self, other):
        return 'Foo iadd: %s + %s' % (self.x, other.x)

class Boo(object):
    def __init__(self, x):
        self.x = x

    def __iadd__(self, other):
        return 'Boo iadd: %s + %s' % (self.x, other.x)


a = Foo(123)
b = Boo(321)
a += b
print (a)

輸出爲 Foo iadd: 123 + 321

看似很正常,然而代碼如下時:

a = Foo(123)
b = Boo(321)
a += b
print a
b += a
print b

在這裏插入圖片描述
報錯顯示:str沒有x這個屬性,但是按照代碼來看,兩個對象都有x屬性呀。

在b += a 這行有錯,也就是說self爲 b,other爲 a。後來試驗了一番,發現將:

return ‘Boo iadd: %s + %s’ % (self.x, other.x)

改爲:

return ‘Boo iadd: %s + %s’ % (self.x, other)

代碼就不會報錯了,但是輸出幾個如下:
  在這裏插入圖片描述
參考:https://www.cnblogs.com/scolia/p/5686267.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章