Hike News
Hike News

Python基礎-反射

Introduction:

  • 在python中執行反射的效率是非常高的
  • 反射定義:
    • 透過字符串的形式,獲取或操作(增、刪、改、查) 物件(object) 中的成員(函數、屬性)

案例1(獲取屬性)

1
2
3
4
5
6
class foo:
def __init__(self,name,age):
self.name = name
self.age = age

obj = foo("Taroballz",26)

該如何使用”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
3
choice = input('>>>')
value = getattr(obj,choice)
print(value)

結果

1
2
3
4
>>>name
Taroballz
>>>age
26


案例2(獲取方法並執行)

getattr方法除了可以拿取物件的屬性外,也可拿取函數的返回值

1
2
3
4
5
6
7
8
class foo:
def __init__(self,name,age):
self.name = name
self.age = age
def show(self):
return "%s-%s" %(self.name,self.age)

obj = foo("Taroballz",26)

欲使用字符串”show”調用class中的show方法,使用getattr辦得到嗎?

取值

1
print(getattr(obj,"show"))

結果

1
bound method foo.show of <__main__.foo object at 0x0074E6B0

  • 返回一個函數物件(可直接加括號執行)

執行函數物件

1
2
3
function = 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
2
setattr(obj,"K1","V1")
print(obj.K1)

結果

1
V1


delattr

刪除物件中的屬性

1
2
delattr(obj,'name')
print(obj.name)

結果

1
AttributeError: 'foo' object has no attribute 'name'


類(class)亦為物件

同樣的,有關反射的內置方法也適用於class(類),因為類也是物件

getattr方法拿取靜態屬性

1
2
3
4
5
6
7
class foo:
VERSION = 1.0
DESCRIPTION = "say something"

if __name__ == '__main__':
print(getattr(foo,"VERSION"))
print(getattr(foo,"DESCRIPTION"))

結果

1
2
1.0
say something


模塊(module)亦為物件

在同級目錄下創建一個s2.py 寫上以下代碼,並導入(import)

1
2
3
4
5
6
7
NAME = '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
6
import s2
r1 = getattr(s2, "NAME")
print(r1)
r2 = getattr(s2, "func")
result = r2()
print(result)

結果

1
2
Taroballz
I am function

獲取模塊中的類

1
2
get_class = getattr(s2,'foo')
print(get_class)

結果(返回一個類)

1
class 's2.foo'

使用返回類創建一個物件,並獲取類中的資訊

1
2
obj = get_class()
print(obj.test)

結果

1
It is a test