【python之路】【之前没搞明白】8面向对象(反射,非常重要)
反射
反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问、检测和修改它本身状态或行为的一种能力(自省)。这一概念的提出很快引发了计算机科学领域关于应用反射性的研究。它首先被程序语言的设计领域所采用,并在Lisp和面向对象方面取得了成绩。
一句话解释:通过字符串的形式操作对象相关的属性
四个函数:
方法 | 作用 |
hasattr(*args, **kwargs) |
返回对象里面是否有这个属性 *args:目标实例、对象。eg:p, Person **kwargs:属性的名字,以字符串形式输入。eg:'name' |
getattr(object, name, default=None) |
获取对象里面的方法 object:目标实例或者方法 name:方面的名字,用字符串形式输入。eg:“walk” default:不知道啥意思 |
setattr(x, y, v)--> x.y=z |
设置一个属性,还可以赋值 1、新设一个属性,绑定到实例上 2、新设一个方法,绑定到实例上,调用时要传参(self) 3、新设一个方法,绑定到类上,调用时不需传参(self) |
delattr(x, y) --> del x.y | 删除一个属性 等同于 del object.attr |
示例:
class Person(): def __init__(self,name,age): self.name = name self.age = age def walk(self): print('walking') if __name__ == '__main__': p = Person('alex',24) #反射、映射、自省 # hasattr 判断是否有这个方法 if hasattr(p,'name'): print('ddd') # getattr 获取这个方法 user_comm = input('>>:').strip() if hasattr(p,user_comm): func = getattr(p,user_comm) func() # setattr 赋值 # 1设立一个属性,绑定到p上 setattr(p,'sex','F') print(p.sex) # 2写个新方法,绑定到实例p上 def talk(self): print('talking') setattr(p,'talk1',talk) p.talk1(p) #需要将实例作为参数传入 # 3方法绑定到类上 setattr(Person,'talk2',talk) p.talk2() #不用传实例作为参数 # delattr delattr(p,'age') # = del p.age p.age # AttributeError: 'Person' object has no attribute 'age' 删了就没有这个属性,当然会报错
模块的反射(一个py文件的反射)
知识点:
__name__ 在当前模块主动执行的情况下(不是被导入的情况下),等于 __main__
在当前模块被其他模块导入的时候,等于 模块名
反射从其它模块导入的方法
反射的应用
了解了反射的四个函数。那么反射到底有什么用呢?它的应用场景是什么呢?
现在让我们打开浏览器,访问一个网站,你单击登录就跳转到登录界面,你单击注册就跳转到注册界面,等等,其实你单击的其实是一个个的链接,每一个链接都会有一个函数或者方法来处理。
没学反射之前的解决方式
class User: def login(self): print('欢迎来到登录页面') def register(self): print('欢迎来到注册页面') def save(self): print('欢迎来到存储页面') while 1: choose = input('>>>').strip() if choose == 'login': obj = User() obj.login() elif choose == 'register': obj = User() obj.register() elif choose == 'save': obj = User() obj.save()
学了反射之后
class User: def login(self): print('欢迎来到登录页面') def register(self): print('欢迎来到注册页面') def save(self): print('欢迎来到存储页面') user = User() while 1: choose = input('>>>').strip() if hasattr(user,choose): func = getattr(user,choose) func() else: print('输入错误。。。。')
动态加载模块
__import__('14.反射') #解释器使用的 import importlib importlib.import_module('14.反射') #官方推荐