Python中的4个反射方法

反射(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不能用于删除方法。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容