Introduction:
- 在python中執行反射的效率是非常高的
- 反射定義:
- 透過字符串的形式,獲取或操作(增、刪、改、查) 物件(object) 中的成員(函數、屬性)
案例1(獲取屬性)
1 | class foo: |
該如何使用”name”(字符串類型)取到”Taroballz”這個name屬性的值?
__dict__
(類特殊成員)
__dict__
方法可查詢物件中的所有屬性,結果為一字典
取值
1 | print(obj.__dict__["name"]) |
得到1
Taroballz
python內置函數
使用getattr
內置方法獲取物件的屬性
- 參數1:欲獲取屬性的物件
- 參數2:獲取何種屬性(字符串)
取值
1 | print(getattr(obj,"name")) |
得到1
Taroballz
Advanced
可藉由用戶輸入獲取相對應屬性的值 ——> 藉由輸入字符串形式拿取相對應屬性之值1
2
3choice = input('>>>')
value = getattr(obj,choice)
print(value)
結果1
2
3
4>>>name
Taroballz
>>>age
26
案例2(獲取方法並執行)
getattr
方法除了可以拿取物件的屬性外,也可拿取函數的返回值
1 | class foo: |
欲使用字符串”show”調用class中的show方法,使用getattr辦得到嗎?
取值
1 | print(getattr(obj,"show")) |
結果1
bound method foo.show of <__main__.foo object at 0x0074E6B0
- 返回一個函數物件(可直接加括號執行)
執行函數物件1
2
3function = getattr(obj,"show")
re_val = function()
print(re_val)
結果1
Taroballz-26
getattr
方法針對類,不管是其屬性或是函數 皆可取得其對應值與返回值
其他針對反射的python內置方法
hasattr
檢測物件中有無其成員(包括屬性&函數)
判斷屬性有無
1 | print(hasattr(obj,'name')) |
結果1
True
判斷函數有無
1 | print(hasattr(obj,"show")) |
結果1
True
setattr
設置 ( 創建 ) 物件中的屬性並賦予值
1 | setattr(obj,"K1","V1") |
結果1
V1
delattr
刪除物件中的屬性
1 | delattr(obj,'name') |
結果1
AttributeError: 'foo' object has no attribute 'name'
類(class)亦為物件
同樣的,有關反射的內置方法也適用於class
(類),因為類也是物件
getattr
方法拿取靜態屬性
1 | class foo: |
結果1
21.0
say something
模塊(module)亦為物件
在同級目錄下創建一個s2.py 寫上以下代碼,並導入(import)1
2
3
4
5
6
7NAME = 'Taroballz'
def func():
return "I am a function"
class foo:
def __init__(self):
self.test = 'It is a test'
在main文件中導入s2.py 並使用getattr
獲取屬性 (s2此時亦為物件)1
2
3
4
5
6import s2
r1 = getattr(s2, "NAME")
print(r1)
r2 = getattr(s2, "func")
result = r2()
print(result)
結果1
2Taroballz
I am function
獲取模塊中的類
1 | get_class = getattr(s2,'foo') |
結果(返回一個類)1
class 's2.foo'
使用返回類創建一個物件,並獲取類中的資訊1
2obj = get_class()
print(obj.test)
結果1
It is a test