一.反射(reflect) 反射指的是一个对象应该具备,可以检测,修改,增加自身属性的能力 反射就是对字符串操作属性 四个内置函数: 1.hasattr(p,'name') 判断某个对象是否存在某个属性 2.getattr(p,'name',None) 从对象中取出属性, 第三个参数默认值,当属性不存在返回默然值 3.setattr(p,'name','123') 为对象添加属性 4.delattr(p,'name') 从对象中删除属性 代码:
class Person: def __init__(self,name,age): self.name = name self.age = age def say_hi(self): print('hi my name is %s'%self.name) p = Person('jack',12) print(p.name) hasattr(p,'name') print(hasattr(p,'name')) if hasattr(p,'name'): print(getattr(p, 'name', None)) print(getattr(p,'name',None)) print(getattr(p,'ane',None)) # None # p.sb = '123' setattr(p,'sb','123') # print(p.sb) delattr(p,'id') print(p.sb)
应用场景: 1.反射其实就是对属性的增删改查,但是如果直接使用内置的 __dict__来操作,语法繁琐,不好理解 2.另一个主要的原因:如果对象不是自己写的是另一方提供的, 我就必须判断这个对象是否满足要求,也就是是否是我需要的属性和方法 3.框架设计方式; 框架代码:
import plugins # 框架已经实现的部分 def run(plugins): while True: cmd = input('请输入指令:') if cmd == 'exit': break # 因为无法确定框架使用者是否传入正确的对象,所以需要使用反射来检测 # 判断对象是否具备处里这个指令的方法 if hasattr(plugins,cmd): # 取出对应方法 func = getattr(plugins,cmd) func() # 执行方法处理指令 else: print('该指令不受支持') print('see you na la') # 创建一个插件对象,调用框架来使用它 wincmd = plugins.WinCMD() # 框架之外的部分就有自定义对象来完成 linux = plugins.LinuxCMD() run(linux)
二.元类 1.创建类的类,就叫做元类 万物皆为对象,类也是对象 对象是通过类实例化产生的,如果类也是对象的话,必然类对象也是有另一类实例化产生的 类用来管理对象,谁来管理类?我们用元类类管理类 默认情况下所有类的元类都是type 2.学习类的目的: 类用来管理对象,谁来管理类?我们用元类类管理类 就是需要对类对象进行一些限制: 想到了用初始化方法,我们只要知道类对象的类(元类), 覆盖其中init方法就能实现 列如:控制类名必须以大驼峰的方式书写
""" 只要继承了type,那么这个类就变成了一个元类 """ # 定义一个元类 class MyType(type): def __init__(self,class_name,bases,dict): super().__init__(class_name,bases,dict) print(class_name,bases,dict) if not class_name.istitle(): raise Exception('类名你不会鞋码:') # 为Pig类指定元类为MyType class Pig(metaclass=MyType): pass # 为 Duck指定元类为MyType class Duck(metaclass=MyType): pass
3.类的三个组成部分 1.类的名称(字符类型) 2.类的父类们(列表或元组) 3.类的名称空间(字典类型) 4.call方法 当你调用类对象时会自动执行元类中__call__方法, 并将这个类本身作为第一个参数传入,以及后面的一堆参数 覆盖元类中__call__方法后,这个类无法产生对象, 必须调用super().__call__来完成对象的创建 并返回其返回值 使用场景: 当你想要控制对象的创建过程时,就覆盖call方法 当你想要控制类的创建过程时,就覆盖call方法 注意: 一旦覆盖了call必须调用父类的call方法类产生对象 并返回这个对象 5.new方法 当你要创建类对象时,会首先执行元类中__new__方法,拿到一个空对象 然后会自动调用__init__来对这个类进行初始化操作 注意:如果你覆盖了该方法则必须保证,new方法必须有返回值,且必须是 对应的类对象 6.单列设计模式 单列:指的是一个类产生一个对象 用来解决某种固定问题的套路 MVC MTV 为什么要使用单列:就是为了节省资源,当一个类的所有属性全部相同时 则没有必要创建多个对象
来源:https://www.cnblogs.com/zhuangshenhao/p/11272509.html