一、反射
1、什么是反射
反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问、检测和修改它本身状态或行为的一种能力(自省)。这一概念的提出很快引发了计算机科学领域关于应用反射性的研究。它首先被程序语言的设计领域所采用,并在Lisp和面向对象方面取得了成绩。
2 、python面向对象中的反射
通过字符串的形式操作对象相关的属性。python中的一切事物都是对象(都可以使用反射)。
类名 ——反射 静态属性
对象名 ——反射 对象属性 和 方法
模块 ——反射模块中的名字
反射 ——自己所在文件中的名字
3、使用说明
首先 使用getattr取获取一个名字,如果在这个对象的命名空间中没有这个名字 会报错;
getattr的反射好伴侣 hasattr 判断在这个对象的命名空间中没有这个名字 存在返回True 否则False;
如果使用getattr取获取一个方法,那么只能拿到这个方法的内存地址 加上括号就是执行,当然,括号里的参数可以照传不误;
如果getattr获取一个属性,那么直接使用反射就可以获取到值。
模块就是一个py文件,pyi代表是内置模块;
所谓的模块导入 就是执行了这个文件而已。
4、四个可以实现自省的函数:hasattr、getattr、setattr、delattr
# 1)四个方法的使用示例 class Foo: f = '类的静态变量' def __init__(self, name, age): self.name = name self.age = age def say_hi(self): print('hi,%s' % self.name) obj = Foo('egon', 73) # 检测是否含有某属性 print(hasattr(obj, 'name')) # >>>True print(hasattr(obj, 'say_hi')) # >>>True # 获取属性 n = getattr(obj, 'name') print(n) # >>>egon func = getattr(obj, 'say_hi') func() # >>>hi,egon # print(getattr(obj,'aaaaaaaa','不存在啊')) #报错 # 设置属性 setattr(obj, 'sb', True) setattr(obj, 'show_name', lambda self: self.name + 'sb') print( obj.__dict__) # >>>{'name': 'egon', 'age': 73, 'sb': True, 'show_name': <function <lambda> at 0x00000292BAE05F28>} print(obj.show_name(obj)) # >>>egonsb # 删除属性 delattr(obj, 'age') delattr(obj, 'show_name') # delattr(obj,'show_name111')#不存在,则报错 print(obj.__dict__) # >>>{'name': 'egon', 'sb': True}
#2)类也是对象 class Foo(object): staticField = "old boy" def __init__(self): self.name = 'wupeiqi' def func(self): return 'func' @staticmethod def bar(): return 'bar' print(getattr(Foo, 'staticField')) print(getattr(Foo, 'func')) print(getattr(Foo, 'bar')) # 执行结果 # old boy # <function Foo.func at 0x000001A8F4739378> # <function Foo.bar at 0x000001A8F4739400>
# 3)反射当前模块的成员 import sys def s1(): print('s1') def s2(): print('s2') this_module = sys.modules[__name__] print(hasattr(this_module, 's1'))#>>>True getattr(this_module, 's2')()#>>>s2
# 4)示例 class Person: role = 'Person' # 静态属性 def __init__(self, name): self.name = name # 对象属性 def eat(self): print('eating') def drink(self): print('drinking') def play(self): print('playing') def sleep(self): print('sleepping') alex = Person('alex') alex.name print(getattr(alex, 'name')) # >>>alex print(getattr(Person, 'role')) # >>>Person while True: inp = input('>>>') if hasattr(alex, inp): getattr(alex, inp)() # 执行结果: # >>>eat # eating # >>>drink # drinking # >>>play # playing # >>>sleep # sleepping # >>>111 # >>>
# 5)反射当前模块成员 # mymodule.py # money = 100 # def func1(): # print('func1') # # def func2(): # print('func2') # # class Manager: # def eat(self): # print('eating') import mymodule import time mymodule.func1()#>>>func1 time.sleep(0.5) print(mymodule.money)#>>>100 getattr(mymodule,'func1')()#>>>func1 print(getattr(mymodule,'money'))#>>>100 getattr(time,'sleep')(1) Manager = getattr(mymodule,'Manager')#拿到一个类的内存地址 a = Manager() a.eat()#>>>eating value = '123' import sys print(sys.modules) #>>>{'builtins': <module 'builtins' (built-in)>, 'sys': <module 'sys' (built-in)>, '_frozen_importlib': <module '_frozen_importlib' (frozen)>, '_imp': <module '_imp' (built-in)>, '_warnings': <module '_warnings' (built-in)>, '_thread': <module '_thread' (built-in)>, '_weakref': <module '_weakref' (built-in)>, '_frozen_importlib_external': <module '_frozen_importlib_external' (frozen)>, '_io': <module 'io' (built-in)>, 'marshal': <module 'marshal' (built-in)>, 'nt': <module 'nt' (built-in)>, 'winreg': <module 'winreg' (built-in)>, 'zipimport': <module 'zipimport' (built-in)>, 'encodings': <module 'encodings' from 'C:\\Users\\28163\\AppData\\Local\\Programs\\Python\\Python36\\lib\\encodings\\__init__.py'>, 'codecs': <module 'codecs' from 'C:\\Users\\28163\\AppData\\Local\\Programs\\Python\\Python36\\lib\\codecs.py'>, '_codecs': <module '_codecs' (built-in)>, 'encodings.aliases': <module 'encodings.aliases' from 'C:\\Users\\28163\\AppData\\Local\\Programs\\Python\\Python36\\lib\\encodings\\aliases.py'>, 'encodings.utf_8': <module 'encodings.utf_8' from 'C:\\Users\\28163\\AppData\\Local\\Programs\\Python\\Python36\\lib\\encodings\\utf_8.py'>, '_signal': <module '_signal' (built-in)>, '__main__': <module '__main__' from 'C:/Users/28163/Desktop/老男孩教育-Python21期/day07/day7视频与笔记/day7笔记/9.反射.py'>, 'encodings.latin_1': <module 'encodings.latin_1' from 'C:\\Users\\28163\\AppData\\Local\\Programs\\Python\\Python36\\lib\\encodings\\latin_1.py'>, 'io': <module 'io' from 'C:\\Users\\28163\\AppData\\Local\\Programs\\Python\\Python36\\lib\\io.py'>, 'abc': <module 'abc' from 'C:\\Users\\28163\\AppData\\Local\\Programs\\Python\\Python36\\lib\\abc.py'>, '_weakrefset': <module '_weakrefset' from 'C:\\Users\\28163\\AppData\\Local\\Programs\\Python\\Python36\\lib\\_weakrefset.py'>, 'site': <module 'site' from 'C:\\Users\\28163\\AppData\\Local\\Programs\\Python\\Python36\\lib\\site.py'>, 'os': <module 'os' from 'C:\\Users\\28163\\AppData\\Local\\Programs\\Python\\Python36\\lib\\os.py'>, 'errno': <module 'errno' (built-in)>, 'stat': <module 'stat' from 'C:\\Users\\28163\\AppData\\Local\\Programs\\Python\\Python36\\lib\\stat.py'>, '_stat': <module '_stat' (built-in)>, 'ntpath': <module 'ntpath' from 'C:\\Users\\28163\\AppData\\Local\\Programs\\Python\\Python36\\lib\\ntpath.py'>, 'genericpath': <module 'genericpath' from 'C:\\Users\\28163\\AppData\\Local\\Programs\\Python\\Python36\\lib\\genericpath.py'>, 'os.path': <module 'ntpath' from 'C:\\Users\\28163\\AppData\\Local\\Programs\\Python\\Python36\\lib\\ntpath.py'>, '_collections_abc': <module '_collections_abc' from 'C:\\Users\\28163\\AppData\\Local\\Programs\\Python\\Python36\\lib\\_collections_abc.py'>, '_sitebuiltins': <module '_sitebuiltins' from 'C:\\Users\\28163\\AppData\\Local\\Programs\\Python\\Python36\\lib\\_sitebuiltins.py'>, '_bootlocale': <module '_bootlocale' from 'C:\\Users\\28163\\AppData\\Local\\Programs\\Python\\Python36\\lib\\_bootlocale.py'>, '_locale': <module '_locale' (built-in)>, 'encodings.gbk': <module 'encodings.gbk' from 'C:\\Users\\28163\\AppData\\Local\\Programs\\Python\\Python36\\lib\\encodings\\gbk.py'>, '_codecs_cn': <module '_codecs_cn' (built-in)>, '_multibytecodec': <module '_multibytecodec' (built-in)>, 'sysconfig': <module 'sysconfig' from 'C:\\Users\\28163\\AppData\\Local\\Programs\\Python\\Python36\\lib\\sysconfig.py'>, 'encodings.cp437': <module 'encodings.cp437' from 'C:\\Users\\28163\\AppData\\Local\\Programs\\Python\\Python36\\lib\\encodings\\cp437.py'>, 'sitecustomize': <module 'sitecustomize' from 'C:\\Program Files\\JetBrains\\PyCharm 2017.3.4\\helpers\\pycharm_matplotlib_backend\\sitecustomize.py'>, 'mymodule': <module 'mymodule' from 'C:\\Users\\28163\\Desktop\\老男孩教育-Python21期\\day07\\day7视频与笔记\\day7笔记\\mymodule.py'>, 'time': <module 'time' (built-in)>} print(sys.modules['__main__']) #>>><module '__main__' from 'C:/Users/28163/Desktop/老男孩教育-Python21期/day07/day7视频与笔记/day7笔记/9.反射.py'> print(getattr(sys.modules['__main__'],'value'))#>>>123 反射自己模块当中的名字
# 6)示例 class Manager: def __init__(self, name): self.name = name def create_course(self): pass class Teacher: def __init__(self, name): self.name = name def list_student(self): pass class Student: def __init__(self, name): self.name = name def create_course(self): pass a = Student('a') a.age = 19 setattr(a, 'age', 25) print(a.__dict__) # >>>{'name': 'a', 'age': 25} print(a.age) # >>>25 import sys # login 先进行登录 # 输入name,pwd 与文件内容比对,然后找到对应身份的类 id = 'Manager' if hasattr(sys.modules['__main__'], id): obj = getattr(sys.modules['__main__'], id)(name, pwd)