Python类的自定义属性访问及动态属性设置
本文主要介紹python類的一些自定義屬性訪問的方法,以及類的動態屬性設置即python的內置函數setattr()。
自定義屬性訪問
? 什么是屬性?下面的例子a和b是屬性嗎?不是,他們是全局變量,屬性(attribute)是類中的成員變量,也可以理解為屬性就是類變量。
a = 11234 b = 'python'類中的變量是靜態變量,類可以直接訪問,python是一門動態語言,任何實例對象都可以動態地添加或刪除屬性,一個類定義了一個作用域,類實例對象也引入了一個作用域,這與類定義的作用域是不同的。在類實例對象中查找屬性的時候,首先在實例自己的作用域中查找,如果沒有找到,則再去類定義的作用域中查找。
在對類實例屬性進行賦值的時候,實際上會在類實例定義的作用域中添加一個屬性或修改一個屬性,但并不會影響到對應類中定義的同名屬性。那么從訪問屬性到返回結果的過程是怎么運作的呢?是通過下面幾個魔術方法來實現的。
相關方法的使用
- __getattribute__:查找屬性時會先觸發該方法進行屬性查找
- __getattr__:查找屬性沒找到的時候觸發
- __setattr__:設置屬性的時候觸發
- __delattr__:刪除屬性的時候觸發
為了直觀地感受實例訪問屬性時都做了什么,我們看一下下面的例子:
class TestCase:att_1 = 'hello' # 定義類屬性att_2 = 'python'def test_func(self): # 定義方法print("這是一個方法")def __getattribute__(self, item):# 屬性訪問攔截器:當對象訪問屬性時,會自動觸發這個方法,由這個方法來決定返回的屬性值# 應用場景:訪問不存在的屬性時,不希望它報錯,可以用try--except來捕獲異常返回一個值或提示信息# try:# return super().__getattribute__(item) # 調用父類真正的__getattribute__方法返回正確的屬性值# except AttributeError:# print(item,':該屬性不存在!')# 如果使用了try方法就不會觸發__getattr__方法了,因為找不到屬性時的異常已經在這里被捕獲了print("我是__getattribute__,我正在工作")return super().__getattribute__(item) # 調用父類的方法,返回找到的結果,不調用就不會返回def __getattr__(self, att_name):# 當對象訪問屬性時,屬性不存在,引發異常,會被__getattr__方法捕獲# 然后執行該方法的代碼,相當于自帶捕獲異常print("我是__getattr__,我正在工作")return att_name + "這是我要找的東西,但是我找不到"def __setattr__(self, att_name, value):# 設置屬性的時候就會觸發該方法print("我是__setattr__,我正在工作")super().__setattr__(att_name, value) # 調用父類的方法,設置屬性,不調用就不會真的設置屬性def __delattr__(self, att_name):print("我是__delattr__,我正在工作")print("這是我即將刪除的東西{}".format(att_name))super().__delattr__(att_name) # 調用父類的方法,刪除屬性,不調用就刪除不了res = TestCase() # 實例化對象 print('-----------------訪問屬性----------------') print(res.att_1) # 訪問類屬性,通過運行結果看res實例對象訪問屬性時通過了方法__getattribute__print('\n-----------------訪問不存在的屬性----------------') print(res.att_3)print('\n-----------------設置屬性----------------') res.att_3 = 'new_attr'print('\n-----------------刪除屬性----------------') del res.att_3運行結果:
-----------------訪問屬性---------------- 我是__getattribute__,我正在工作 hello-----------------訪問不存在的屬性---------------- 我是__getattribute__,我正在工作 我是__getattr__,我正在工作 att_3這是我要找的東西,但是我找不到-----------------設置屬性---------------- 我是__setattr__,我正在工作-----------------刪除屬性---------------- 我是__delattr__,我正在工作 這是我即將刪除的東西att_3從結果中,我們可以看到當實例訪問屬性時,就會自動觸發__getattribute__()方法,然后由這個方法來決定返回的屬性值;當實例訪問不存在的屬性時,會引發異常,而這個異常會被__getattr__()方法捕獲,然后執行該方法的代碼,相當于自帶捕獲異常;同理,在設置屬性或刪除屬性時,會自動觸發對應的__setattr__()方法或__delattr__()方法。
? 但需要注意的是,在自定義這些方法的時候,一定要記得調用對應的父類方法,將結果返回,否則只是執行了你自定義的東西并沒有真正去做它本身要去做的事情。
動態屬性設置
? setattr()是python的一個內置函數,用于動態設置實例屬性,語法:setattr(object, name, value)
-
參數1:object-對象
-
參數2:name-給對象要設置的屬性名(字符串類型)
-
參數3:value-屬性值
運行結果:
[<__main__.TestCase object at 0x0000019F15F573C8>, <__main__.TestCase object at 0x0000019F15F57C18>, <__main__.TestCase object at 0x0000019F16009C18>, <__main__.TestCase object at 0x0000019F16009C50>]按字段讀取第一條測試用例數據: case_id: 1 data: 123 actual: 不通過 excepted: 通過讀取完整的第一條測試用例數據: {'case_id': 1, 'data': '123', 'actual': '不通過', 'excepted': '通過'}上面的運行結果中,像<main.TestCase object at 0x0000019F15F573C8>這就是一個TestCase()類的實例對象,這是它的內存地址,setattr()動態設置屬性,就相當于case.case_id=1給實例設置一個屬性,只是上面所舉例是循環地把整個列表的數據拆分成4個實例的屬性。
? 同樣的,python中對應還有一個getattr(object, name)內置函數,它是用于返回一個實例的屬性,需要兩個參數,一個是對象名,一個是屬性名,返回該屬性的屬性值,這里不再舉例,自己使用一下吧!
? 另外,上述例子中最后還用到了一個__dict__對象屬性,它是用于獲取實例對象的所有屬性,并以字典的形式返回。
結尾給大家推薦一個非常好的學習教程,希望對你學習Python有幫助!
Python基礎入門教程推薦:更多Python視頻教程-關注B站:Python學習者
Python爬蟲案例教程推薦:更多Python視頻教程-關注B站:Python學習者
總結
以上是生活随笔為你收集整理的Python类的自定义属性访问及动态属性设置的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 两种思路将Python中两个有序数组合并
- 下一篇: Python基础入门必学内容:判断语句与