反射(reflection)蓄氧,指的是運(yùn)行時獲取類型定義信息函似,如type、class喉童、attribute或method撇寞,有人也會稱這種機(jī)制為自省。簡單來講,就是通過字符串去操作對象的屬性和方法蔑担,類似于我們在瀏覽器中輸入網(wǎng)址牌废,返還給我們頁面一樣。
反射是編程語言中的一種高級操作方式啤握,是在程序運(yùn)行過程中鸟缕,動態(tài)的從內(nèi)存中獲取執(zhí)行狀態(tài),根據(jù)執(zhí)行狀態(tài)動態(tài)調(diào)用執(zhí)行棧恨统,完成具體功能的操作叁扫。
Python為我們提供了4個關(guān)于反射的內(nèi)置函數(shù)三妈。
hasattr(object,name)
該函數(shù)用于判斷一個對象是否有對應(yīng)的方法或?qū)傩孕舐瘢祷豣ool值。需要注意的是畴蒲,name必須為字符串悠鞍。
class Animal:
come_from = "earth"
def __init__(self, name):
self.name = name
def eat(self):
print("eat")
dog = Animal("dog")
print(hasattr(dog, "come_from"))
# True
print(hasattr(dog, "name"))
# True
print(hasattr(dog, "eat"))
# True
print(hasattr(dog, "work"))
# False
getattr(object,name[,default])
通過name返回object的屬性值,當(dāng)屬性不存在模燥,將使用default返回咖祭,如果沒有default,則拋出AttributeError蔫骂。同樣么翰,name必須為字符串。
class Animal:
come_from = "earth"
def __init__(self, name):
self.name = name
def eat(self):
print("eat")
dog = Animal("dog")
print(getattr(dog, "come_from"))
# earth
print(getattr(dog, "name"))
# dog
print(getattr(dog, "eat"))
# <bound method Animal.eat of <__main__.Animal object at 0x0000013F08E69AC8>>
print(getattr(dog, "work", 'not found...'))
# not found...
由上述案例可以看出辽旋,getattr主要用來獲取對象屬性的值浩嫌。當(dāng)然,name也可以是方法补胚,但返回的是一個方法對象码耐。
如果要使方法執(zhí)行,可以在getattr方法后面加()溶其。
class Animal:
def __init__(self, name):
self.name = name
def eat(self):
print("hungry")
return "eat"
dog = Animal("dog")
print(getattr(dog, "eat")())
# hungry
# eat
setattr(object,name,value)
為object新增屬性name骚腥,值為value,有則覆蓋瓶逃,不存在則新增束铭。
class Animal:
come_from = "earth"
def __init__(self, name):
self.name = name
def eat(self):
print("eat")
dog = Animal("dog")
if not hasattr(dog, "age"):
setattr(dog, "age", 18)
print(getattr(dog, "age"))
# 18
值得注意的是,setattr添加的屬性是可以被繼承的厢绝。也就是說契沫,如果對上述案例的Animal類添加屬性,dog也會存在該屬性代芜。
delattr(object, name)
根據(jù)方法名便可看出埠褪,該方法是用于刪除object的name屬性。
class Animal:
come_from = "earth"
def __init__(self, name):
self.name = name
def eat(self):
print("eat")
alien = Animal("alien")
if getattr(alien, "come_from") == "earth":
delattr(Animal, "come_from")
print(getattr(alien, "come_from", "該屬性已被刪除..."))
# 該屬性已被刪除...
通過上述案例可發(fā)現(xiàn),那就是delattr不可以刪除父類的屬性钞速,也就是不可以通過dog來刪除come_from贷掖。需要使用父類Animal來刪除。并且渴语,delattr不能用于刪除方法苹威。