""" 一、isinstance(obj,cls) 和 issubclass(sub,super) isinstance(obj,cls) 检查obj是否是类cls的对象 class Bar(object): pass class Foo(object): pass obj = Foo() print(isinstance(obj,Foo)) #True print(isinstance(obj,Bar)) #False issubclass(sub,super) 检查sub类是否是super类的子类(派生类) class Bar(object): pass class Foo(Bar): pass class Te(object): pass print(issubclass(Foo,Bar)) #True print(issubclass(Te,Bar)) #False """ """ 二、反射:通过字符串的方式操作对象相关的属性,python中的一切事物都是对象,都可以使用反射 hasattr(object,name) 判断object中有没有一个name字符串对应的方法或者是属性 getattr(object,name,default=None) 从object中获取name属性,如果没有返回默认值None setattr(obj,x,y) 给obj对象设置属性x=y delattr(obj,x) 删除对象obj里的x属性 类也是对象,也可以有这四个方法 使用方法测试: class Foo(object): name = "我是你的什么啊?" def __init__(self,addr): self.addr = addr obj = Foo("去你大爷的") print(hasattr(obj,"name")) #True print(getattr(obj,"name")) #我是你的什么啊? setattr(obj,"sb",True) print(obj.__dict__) #{‘addr‘: ‘去你大爷的‘, ‘sb‘: True} delattr(obj,"sb") print(obj.__dict__) #{‘addr‘: ‘去你大爷的‘} 反射当前模块成员: import sys def s1(): print("s1") def s2(): print("s2") this_module = sys.modules[__name__] print(hasattr(this_module,"s1")) 使用反射的好处: 实现代码的可插拔机制;在导入模块方面经常使用反射;动态的导入模块 三、__setattr__,__delattr__,__getattr__; #__setattr__添加/修改属性会触发它的执行 #__delattr__删除属性的时候会触发 #__getattr__只有在使用点调用属性且属性不存在的时候才会触发 四、二次加工标准类型(包装) class List(list): #继承list所有的属性,也可以派生出自己新的,比如append和mid def append(self, p_object): ‘ 派生自己的append:加上类型检查‘ if not isinstance(p_object,int): raise TypeError(‘must be int‘) super().append(p_object) #调用父类的append方法 @property def mid(self): ‘新增自己的属性‘ index=len(self)//2 return self[index] 实现授权的关键点就是覆盖__getattr__方法 import time class FileHandle: def __init__(self,filename,mode=‘r‘,encoding=‘utf-8‘): self.file=open(filename,mode,encoding=encoding) def write(self,line): t=time.strftime(‘%Y-%m-%d %T‘) self.file.write(‘%s %s‘ %(t,line)) def __getattr__(self, item): return getattr(self.file,item) f1=FileHandle(‘b.txt‘,‘w+‘) f1.write(‘你好啊‘) f1.seek(0) print(f1.read()) f1.close() 五、__getattribute__: 和__getattr__类似,不过不管是否存在都会执行 class Foo: def __init__(self,x): self.x = x def __getattribute__(self, item): print("我总会执行") obj = Foo(10) print(obj.x) print(obj.xxx) !当getattr和getattribute同事存在的时候只执行getattribute,除非抛出异常,两者一起执行 六、描述符(__get__,__set__,__delete__): 什么是描述符:描述符的本质就是一个新式类,在这个新式类中至少实现了__get__(),__set__(),__delete__()中的一个 这也被称为描述符协议 __get__():调用一个属性的时候触发 __set__():为一个属性赋值的时候触发 __delete__():删除属性的时候触发 class Foo: #这个类称为描述符 def __get__(self, instance, owner): pass def __set__(self, instance, value): pass def __delete__(self, instance): pass 描述符的作用:用来代理另外一个类的属性(必须把描述符定义为这个类的类属性,不能定义到构造方法中) 分类: 数据描述符:至少实现了__get__() 和__set__()方法 非数据描述符:没有实现__set__()方法 注意事项: 1、描述符本身应该定义为新式类,被代理的类也应该是新式类 2、必须定义为类属性,不能定义到构造函数中 3、要严格遵循优先级,优先级由高到低分别是(类属性,数据描述符,实例属性,非数据描述符,找不到的时候触发__getattr__()) 描述符的使用: 描述符的总结: 六、property: 一个静态属性property本质就实现了get,set,delete三种方法 用法一: class Foo: @property def AAA(self): print("get的时候运行") @AAA.setter def AAA(self,value): print("set的时候运行",value) @AAA.deleter def AAA(self): print("delete 的时候运行") obj = Foo() obj.AAA #get obj.AAA = "aaa" #set del obj.AAA #delete 用法二: class Foo: def get_AAA(self): print("get的时候yunx") def set_AAA(self,value): print("set 的时候运行") def delete_AAA(self): print("delete的时候运行") AAA=property(get_AAA,set_AAA,delete_AAA) #内置的property三个参数必须与get,set,delete一一对应 七、__setitem__,__getitem__,__delitem__: 示例代码; class Foo: def __init__(self,name): self.name = name def __getitem__(self, item): print(self.__dict__[item]) def __setitem__(self, key, value): self.__dict__[key] = value def __delitem__(self, key): print("del obj 时执行") def __delattr__(self, item): print("del obj 执行,") self.__dict__.pop(item) obj = Foo("sb") obj["age"] = 18 obj["age1"] = 19 del obj.age1 del obj["age"] obj["name"] = "alex" print(obj.__dict__) 八、__str__,__repr__,__format__: 改变对象的字符串显示__str__,__repr__,当你打印对象的时候假如里面没有这两个方法,那么打印出来的你是看不懂的 自定义格式化字符串:__format__ str函数或者print函数--->obj.__str__() repr或者交互式解释器--->obj.__repr__() 如果__str__没有被定义,那么就会使用__repr__来代替输出 注意:这俩方法的返回值必须是字符串,否则抛出异常 - 示例: format_dict={ ‘nat‘:‘{obj.name}-{obj.addr}-{obj.type}‘,#学校名-学校地址-学校类型 ‘tna‘:‘{obj.type}:{obj.name}:{obj.addr}‘,#学校类型:学校名:学校地址 ‘tan‘:‘{obj.type}/{obj.addr}/{obj.name}‘,#学校类型/学校地址/学校名 } class School: def __init__(self,name,addr,type): self.name=name self.addr=addr self.type=type def __repr__(self): return ‘School(%s,%s)‘ %(self.name,self.addr) def __str__(self): return ‘(%s,%s)‘ %(self.name,self.addr) def __format__(self, format_spec): if not format_spec or format_spec not in format_dict: format_spec=‘nat‘ fmt=format_dict[format_spec] return fmt.format(obj=self) s1=School(‘oldboy1‘,‘北京‘,‘私立‘) print(‘from repr: ‘,repr(s1)) print(‘from str: ‘,str(s1)) print(s1) print(format(s1,‘nat‘)) print(format(s1,‘tna‘)) print(format(s1,‘tan‘)) print(format(s1,‘asfdasdffd‘)) 九、__slots__: 在类中写一个slots,在吧类中的某些字段写在里面,外部才可以访问,不写访问不到 十、__next__和__iter__实现迭代器协议 模拟实现range方法: class Range: def __init__(self,n,stop,step): self.n=n self.stop=stop self.step=step def __next__(self): if self.n >= self.stop: raise StopIteration x=self.n self.n+=self.step return x def __iter__(self): return self for i in Range(1,7,3): # print(i) 十一、__doc__ - 显示描述信息,即注释信息 - 无法被继承 十二、__module__和__class__ - __module__ 表示当前操作的对象在哪个摸快 - __class__表示当前操作的对象的类是什么 十三、__del__: - 析构方法:当对象在内存中被释放时执行这段代码 - 比如在数据库链接中关闭数据库,文件操作中的close操作 十四、__enter__和__exit__: __enter__在进来的时候执行 __exit__在出去的时候执行 - 对象调用前后执行这两个方法 十五、__call__方法: - 对象后边+括号自动触发执行 - 构造方法的执行是由创建对象触发的,即对象=类名();而对于__call__方法是对象()或者类()() 十六、metaclass exec:三个参数 字符串形式的命令 全局作用域 局部作用域 exec会在指定的局部作用域内执行字符串内的代码,除非明确地使用global关键字 - 类也是对象 - 什么是元类 - 元类是类的类,类的模板 - 元类是用来控制如何创建类的,正如类是创建对象的模板一样,而元类的主要目的是为了控制类的创建行为元类的实例化的结 果为我们用class定义的类,正如类的实例为对象(f1对象是Foo类的一个实例,Foo类是 type 类的一个实例)type是python的一 个内建元类,用来直接控制生成类,python中任何class定义的类其实都是type类实例化的对象 - 创建类的两张方式: - 方式一:使用class关键字 - 方式二:手动模拟class创建类的过程 - 类名 - 类的父类 - 类体 #类名 class_name=‘Chinese‘ #类的父类 class_bases=(object,) #类体 class_body= country=‘China‘ " def __init__(self,name,age): self.name=name self.age=age def talk(self): print(‘%s is talking‘ %self.name) " - 一个类没有声明自己的元类,默认它的元类就是type,除了使用元类type,用户也可以通过继承type俩自定义元类 - #元类控制类的实例化过程: 1 类(),调用元类.__call__() 2 在1的方法中调用: 类.__new__() #返回类的对象obj 类.__init__(obj,...) #为对象进行初始化 - 元类控制类本身的产生过程 """