本文共 3704 字,大约阅读时间需要 12 分钟。
反射主要是指程序可以访问、检测和修改它本身状态或行为的一种能力(自省)。
python面向对象中的反射就是通过字符串获取对象或者类的属性,进行操作~,主要是对这4个方法的应用:hasattr,getattr,setattr,delattr。class Person: def __init__(self, name, age): self.__name = name self.__age = age def __fun(self): print(self.__class__) def say(self): print(self.__name + ' ' + str(self.__age))# 判断属性是否存在p = Person('baby', 18)print(hasattr(p, 'name')) # Falseprint(hasattr(p, '_Person__name')) # Trueprint(hasattr(p, 'say')) # True# 获取属性fun = getattr(p, 'say')fun() # baby 18,执行反射获取的方法name = getattr(p, '_Person__name')print(name) # baby# 若是属性不存在则报错# age = getattr(p, 'age') # 'Person' object has no attribute 'age'# 设置属性setattr(p, 'sex', 'male') # 设置的是对象的属性,存放在对象的名称空间中# 这里设置的方法是普通方法,存放在对象的名称空间中,self.__name不会变形为 self._Person__name# setattr(p, 'show_name', lambda self: self.__name) setattr(p, 'say_hello', lambda self: 'Hello ' + self._Person__name)print(p.__dict__) # {'_Person__name': 'baby', '_Person__age': 18, 'sex': 'male', 'say_hello':at 0x10f7bf2f0>}print(p.say_hello(p)) # 不是绑定方法,需要手动传值# 删除属性delattr(p, 'sex')print(p.__dict__)# {'_Person__name': 'baby', '_Person__age': 18, 'say_hello': at 0x10f7bf2f0>}# 若不存在该属性则报错# delattr(p, 'name') # AttributeError: name
Tip:
class Person: def __init__(self, name, age): self.__name = name self.__age = age self.city = 'NB' def __fun(self): print(self.__class__) def say(self): print(self.__name + ' ' + str(self.__age)) @classmethod def play(cls): print(cls.__name__) @staticmethod def sleep(): print('sleep...')# 判断属性是否存在print(hasattr(Person, 'name')) # Falseprint(hasattr(Person, '_Person__name')) # False,私有属性 __name,__age 属于对象print(hasattr(Person, 'say')) # True# 获取属性fun = getattr(Person, 'say')p = Person('baby', 18)fun(p) # baby 18,等同于Person.say(p),需要手动传递self# 若是属性不存在# age = getattr(Person, 'age') # 报错,'Person' object has no attribute 'age'# 设置属性setattr(Person, 'sex', 'male') # 设置的是类的静态属性setattr(Person, 'show_city', lambda self: self.city) # 这里通过类设置的方法为绑定到对象的方法,通过对象调用的时候能够自动传值(self)print(p.show_city()) # NB# setattr(Person, 'show_name', lambda self: self.__name) # self.__name 不会自动转换为 self._Person__name# print(p.show_name()) # AttributeError: 'Person' object has no attribute '__name'# 删除属性delattr(Person, 'sex') # 删除的是类的静态属性# 获取类方法getattr(Person, 'play')() # 会完成自动传值,默认将Person作为第一个参数传递给play方法# 获取静态方法getattr(Person, 'sleep')()
Tip:
import sysdef s1(): print('s1')def s2(): print('s2')this_module = sys.modules[__name__]# 判断模块中是否存在 s1 方法print(hasattr(this_module, 's1')) # True# 获取模块中的方法并执行getattr(this_module, 's2')() # s2
sys.modules[__name__] 也可以写成 sys.modules['__main__'],但是不建议这么写,因为当前的模块被导入到另外一个模块的时候,这个被导入的模块使用 sys.modules['__main__'] 就获取不到它的内存地址了~
操作的对象也可以是导入的模块# module_testdef test(): print('from test')# test.pyimport module_testprint(hasattr(module_test,'test')) # Truegetattr(module_test, 'test')() # from test
isinstance 方法用来判断 一个对象 和 一个类之间的关系,即这个对象是不是由这个类实例化而来
class Person: passp = Person()print(isinstance(p, Person)) # True
issubclass 用来判断两个类之间是否存在继承关系
class Father: passclass Son(Father): passprint(issubclass(Son, Father)) # True
.................^_^
转载于:https://blog.51cto.com/ljbaby/2348710