Python 魔法方法(三) __getattr__,__setattr__, __delattr__

1、__getattr__
當我們訪問一個不存在的屬性的時候,會拋出異常,提示我們不存在這個屬性。而這個異常就是__getattr__方法拋出的,其原因在於他是訪問一個不存在的屬性的最後落腳點,作爲異常拋出的地方提示出錯再適合不過了。

看例子,我們找一個存在的屬性和不存在的屬性。

class A(object):
    def __init__(self, value):
        self.value = value
 
    def __getattr__(self, item):
        print "into __getattr__"
        return  "can not find"
 
a = A(10)
print a.value
# 10
print a.name
# into __getattr__
# can not find
可以看出,訪問存在的屬性時,會正常返回值,若該值不存在,則會進入最後的兜底函數__getattr__。

2、__setattr__
在對一個屬性設置值的時候,會調用到這個函數,每個設置值的方式都會進入這個方法。

class A(object):
    def __init__(self, value):
        print "into __init__"
        self.value = value
 
    def __setattr__(self, name, value):
        print "into __setattr__"
        if value == 10:
            print "from __init__"
        object.__setattr__(self, name, value)
 
 
a = A(10)
# into __init__
# into __setattr__
# from __init__
print a.value
# 10
a.value = 100
# into __setattr__
print a.value
# 100
在實例化的時候,會進行初始化,在__init__裏,對value的屬性值進行了設置,這時候會調用__setattr__方法。

在對a.value重新設置值100的時候,會再次進入__setattr__方法。

需要注意的地方是,在重寫__setattr__方法的時候千萬不要重複調用造成死循環。

比如:

class A(object):
    def __init__(self, value):
        self.value = value
 
    def __setattr__(self, name, value):
        self.name = value
這是個死循環。當我們實例化這個類的時候,會進入__init__,然後對value進行設置值,設置值會進入__setattr__方法,而__setattr__方法裏面又有一個self.name=value設置值的操作,會再次調用自身__setattr__,造成死循環。

除了上面調用object類的__setattr__避開死循環,還可以如下重寫__setattr__避開循環。

class A(object):
    def __init__(self, value):
        self.value = value
 
    def __setattr__(self, name, value):
        self.__dict__[name] = value
 
 
a = A(10)
print a.value
# 10
3、__delattr__
__delattr__是個刪除屬性的方法

class A(object):
    def __init__(self, value):
        self.value = value
 
    def __delattr__(self, item):
        object.__delattr__(self, item)
 
    def __getattr__(self, item):
        return "when can not find attribute into __getattr__"
 
 
 
a = A(10)
print a.value
# 10
del a.value
print a.value
# when can not find attribute into __getattr__
__delattr__也要避免死循環的問題,就如__setattr__一樣,在重寫__delattr__,避免重複調用。
————————————————
版權聲明:本文爲CSDN博主「yusuiyu」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/yusuiyu/article/details/87945149

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