零基礎入門學習Python(23):魔法方法(3)屬性訪問

零基礎入門學習Python(23):魔法方法(3)屬性訪問

在講解今天的內容之前,我們先重寫兩個函數__str__()和__repr__(),第一個函數表示可以使用print()打印對象的值,第二個函數表示直接寫出對象名就可以打印出對象的值。

>>> class Test:
        def __str__(self):
            return "Hello everyone."

>>> t1 = Test()
>>> t1                                 #直接寫出t1得到它在內存中的位置
<__main__.Test object at 0x028859F0>
>>> print(t1)                          #需要調用print()才能打印出對象的值
Hello everyone.
>>> class Test:
        def __repr__(self):
            return "Hello everyone"

>>> t2 = Test()                        #重寫__repr__()之後寫出t2,則可以直接得到對象的值
>>> t2
Hello everyone

下面介紹一下Python屬性訪問的魔法方法:
1)__getattr__(self,name):定義當用戶試圖獲取一個不存在的屬性時的行爲;
2)__getattribute__(self,name):定義當該類的屬性被訪問時的行爲;
3)__setattr__(self,name,value):定義當一個屬性被設置時的行爲;
4)__delattr__(self,name):定義當一個屬性被刪除時的行爲;

在訪問屬性的方法調用的時候,會先調用__getattribute__(self,name)方法,當屬性不存在時再調用__getattr__(self,name)方法,下面通過舉例驗證一下。

>>> class TestAttr:
        def __getattribute__(self,name):           #分別重寫屬性訪問的魔法方法
            print('getattribute...')
            return super().__getattribute__(name)  #返回值調用沒重寫時候的方法
        def __getattr__(self,name):
            print('getattr...')
        def __setattr__(self,name,value):
            print('setattr...')
            super().__setattr__(name,value)
        def __delattr__(self, name):
            print('delattr...')
            super().__delattr__(name)

>>> a1 = TestAttr()
>>> a1.x                                            #x屬性不存在,則先調用__getattribute__()方法,再調用__getattr__()方法
getattribute...
getattr...
>>> a1.x = 2                                        #設置對象的x屬性
setattr...
>>> a1.x                                            #再次訪問x時,則直接調用__getattribute__()方法並顯示出x的值
getattribute...
2
>>> del a1.x                                        #刪除對象的x屬性
delattr...

最後舉一個例子:寫一個矩形類,要求長寬默認爲0,如果爲一個叫square的屬性賦值,說明是一個正方形,則長寬都等於square,最後計算矩形的面積。

>>> class Rectangle:
        def __init__(self, length = 0, width = 0):
            self.length = length             #賦值操作,會進到__setattr__()方法中
            self.width = width
        def __setattr__(self, name, value):  #重寫__setattr__()方法
            if name == "square":             #先判斷是否爲正方形
                self.length = value
                self.width = value
            else:                            #如果不是,則調用未重寫時候設置屬性的方法
                super().__setattr__(name, value)

        def getArea(self):
            return self.length * self.width

>>> r1 = Rectangle(2,3)                      #初始化長寬
>>> r1.getArea()
6
>>> r1.length = 5                            #可以只改變長或寬的值
>>> r1.getArea()
15
>>> r1.square = 7                            #給square賦值時,長寬相等
>>> r1.length
7
>>> r1.width
7
>>> r1.getArea()
49
>>> r1.__dict__                              #顯示對象r1的屬性
{'width': 7, 'length': 7}

由於對象的屬性組成了一個字典類型的對象,所以設置屬性時,除了可以使用super()方法之外,還可以利用字典的鍵值對給屬性賦值,即super().__setattr__(name, value)這行代碼可以改爲self.__dict__[name] = value。當然,推薦大家使用super()方法。

零基礎入門學習Python(22):魔法方法(2)算術運算

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