
反射(reflection),指的是运行时获取类型定义信息,如type、class、attribute或method,有人也会称这种机制为自省。简单来讲,就是通过字符串去操作对象的属性和方法,类似于我们在浏览器中输入网址,返还给我们页面一样。
反射是编程语言中的一种高级操作方式,是在程序运行过程中,动态的从内存中获取执行状态,根据执行状态动态调用执行栈,完成具体功能的操作。
Python为我们提供了4个关于反射的内置函数。
hasattr(object,name)
该函数用于判断一个对象是否有对应的方法或属性,返回bool值。需要注意的是,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的属性值,当属性不存在,将使用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主要用来获取对象属性的值。当然,name也可以是方法,但返回的是一个方法对象。
如果要使方法执行,可以在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)
根据方法名便可看出,该方法是用于删除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", "该属性已被删除..."))
# 该属性已被删除...
通过上述案例可发现,那就是delattr不可以删除父类的属性,也就是不可以通过dog来删除come_from。需要使用父类Animal来删除。并且,delattr不能用于删除方法。