python面向对象getattr\setattr\delattr\hasattr

getattr\setattr\delattr\hasattr


hasattr

hasattr用反射机制来判断对象是否含有某属性

hasattr使用例子:
class People:
    def __init__(self,name,sex):
        self.name,self.sex = name,sex
someone = People("handsomeCharl", 'male')
if hasattr(someone,'age'):
    print(someone.age)

getattr

getattr用来获取对象属性或方法
结合上一个例子,用getattr来获取一个run方法:
class People:
    def __init__(self,name,sex):
        self.name,self.sex = name,sex
    def run(self):
        print("%s is running!" %self.name)
someone = People("handsomeCharl", 'male')
if hasattr(someone,'run'):
    methods = getattr(someone, 'run')
methods()
'''
OUTPUT:
handsomeCharl is running!
'''

setattr

setattr用来设置属性
为对象加一个年龄属性:
class People:
    def __init__(self,name,sex):
        self.name,self.sex = name,sex
    def run(self):
        print("%s is running!" %self.name)
someone = People("handsomeCharl", 'male')
if not hasattr(someone,'age'): #如果age属性不存在就执行setattr
    setattr(someone, 'age', 100)
print(someone.age)
'''
OUTPUT:
100
'''

delattr

delattr用来删除属性
删除对象的sex属性:
class People:
    def __init__(self,name,sex):
        self.name,self.sex = name,sex
    def run(self):
        print("%s is running!" %self.name)
someone = People("handsomeCharl", 'male')
if not hasattr(someone,'sex'):
    delattr(someone, 'sex')
print(someone.__dict__)
'''
OUTPUT:
{'sex': 'male', 'name': 'handsomeCharl'}
'''

反射机制

简单的说就是用字符串来获取属性/方法或者判断是否存在,反射机制的好处就是能把需要用到的函数等通过字符串的形式来获取到

__getattr__,__setattr__,__delattr__


__getattr__

与getattr()不同的是getattr()是内建函数,而__getattr__是内建方法,作用于类
__getattr__是让class外部获取obj属性的接口
当obj.something执行时会先检索obj.__dict__再从__getattr__中获取响应的属性
举个栗子:
class People:
    def __init__(self,name):
        self.name = name
    def __getattr__(self,value):
        print("not found %s" %value)
charl = People("handsomeCharl")
print(charl.name)
charl.age
''' 
output:
handsomeCharl
not found age
'''

setattr

__setattr__设置对象属性,添加、修改属性时会自动调用这个接口
修改上面的栗子,加入__setattr__:
class People:
    def __init__(self,name):
        self.name = name
    def __getattr__(self,value):
        if not hasattr(self,value):
            print("not found %s" %value)
    def __setattr__(self,key,value):
        print("set tag") #做个记号 代表setattr执行过
        self.__dict__[key] = value #self.key = value会引起死循环,每次赋值都会执行__setattr__这个内建方法
charl = People("handsomeCharl")
charl.age = 100
print(charl.age)
''' 
output:
set tag #第一个set tag的输出是在建立对象的时候
set tag
100
'''

delattr

__delattr__和setattr差不多,删除对象属性的时候调用该接口
再修改上面的栗子,加入__delattr__:
class People:
    def __init__(self,name):
        self.name = name
    def __getattr__(self,value):
        print("not found %s" %value)
    def __setattr__(self,key,value):
        print("set tag")
        self.__dict__[key] = value
    def __delattr__(self,key):
        print("del tag")
        self.__dict__.pop(key)
charl = People("handsomeCharl")
charl.age = 100
print(charl.age)
del charl.age
charl.age
''' 
output:
set tag #建立对象时调用了setattr接口
set tag #增加age属性调用了setattr接口
100
del tag #删除age属性调用了delattr接口
not found age #找不到age属性调用getattr接口
'''

Leave a Reply

Your email address will not be published. Required fields are marked *