反射主要是指程序能够访问、检测和修改它自己状态或行为的一种能力(自省)。
python面向对象中的反射就是经过字符串获取对象或者类的属性,进行操做~,主要是对这4个方法的应用:hasattr,getattr,setattr,delattr。python
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')) # False print(hasattr(p, '_Person__name')) # True print(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': <function <lambda> at 0x10f7bf2f0>} print(p.say_hello(p)) # 不是绑定方法,须要手动传值 # 删除属性 delattr(p, 'sex') print(p.__dict__) # {'_Person__name': 'baby', '_Person__age': 18, 'say_hello': <function <lambda> at 0x10f7bf2f0>} # 若不存在该属性则报错 # delattr(p, 'name') # AttributeError: name
Tip:ide
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')) # False print(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:this
import sys def 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__'] 就获取不到它的内存地址了~
操做的对象也能够是导入的模块code
# module_test def test(): print('from test') # test.py import module_test print(hasattr(module_test,'test')) # True getattr(module_test, 'test')() # from test
isinstance 方法用来判断 一个对象 和 一个类之间的关系,即这个对象是否是由这个类实例化而来对象
class Person: pass p = Person() print(isinstance(p, Person)) # True
issubclass 用来判断两个类之间是否存在继承关系继承
class Father: pass class Son(Father): pass print(issubclass(Son, Father)) # True
.................^_^ip