#(1)__init__:初始化 #(2)__str__:在打印时改变对象的字符串显示,在打印类的时候会调用此方法,返回的是一个字符串 #(3)__repr__ #(4)__new__:创建对象。执行__init__之前执行__new__方法,在单例/rest framework序列化中使用过 #在rest framework序列化源码中的使用 class BaseSerializer(Field): def __init__(self, instance=None, data=empty, **kwargs): self.instance = instance if data is not empty: self.initial_data = data self.partial = kwargs.pop('partial', False) self._context = kwargs.pop('context', {}) kwargs.pop('many', None) super().__init__(**kwargs) def __new__(cls, *args, **kwargs): # We override this method in order to automagically create # `ListSerializer` classes instead when `many=True` is set. if kwargs.pop('many', False): return cls.many_init(*args, **kwargs) return super().__new__(cls, *args, **kwargs) #(5)__call__:对象()触发。flask源码请求入口,django请求入口(WSGIHandler.__call__)。 #在flask源码请求入口中的使用 class Flask(_PackageBoundObject): def __call__(self, environ, start_response): return self.wsgi_app(environ, start_response) #在django源码请求入口中的使用 class WSGIHandler(base.BaseHandler): request_class = WSGIRequest def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.load_middleware() def __call__(self, environ, start_response): set_script_prefix(get_script_name(environ)) signals.request_started.send(sender=self.__class__, environ=environ) request = self.request_class(environ) response = self.get_response(request) #…… #(6)__getattr__ :对象.属性 触发 #(7)__setattr__:对象.属性 = xxx 触发 #(8)__delattr__:在flask源码Local对象中使用了这三个,见最下方 #(9)__setitem__ #(10)__getitem__ #(11)__delitem__ :对象['xx']会触发这个三个 class Foo(object): def __getitem__(self, item): return 1 def __setitem__(self, key, value): pass def __delitem__(self, key): pass obj = Foo() obj['k1'] #触发__getitem__ obj['k1'] = 123 #触发__setitem__ del obj['k1'] #触发__delitem__ #(12)__dict__,api封装返回数据时:BaseResponse #(13)__mro__, 继承顺序 #(14)__slots__,Local对象
#(15)__iter__,一个类中如果含此方法并返回一个迭代器,那么这个对象就是一个可迭代对象
#flask源码Local对象 class Local(object): __slots__ = ('__storage__', '__ident_func__') #__slots__中设置的值就是外部能访问的值 def __init__(self): # __storage__ = {1231:{'stack':[]}} object.__setattr__(self, '__storage__', {}) object.__setattr__(self, '__ident_func__', get_ident) def __getattr__(self, name): try: return self.__storage__[self.__ident_func__()][name] except KeyError: raise AttributeError(name) def __setattr__(self, name, value): ident = self.__ident_func__() #相当于ident = get_ident() storage = self.__storage__ #相当于storge = {} try: storage[ident][name] = value except KeyError: storage[ident] = {name: value} #唯一标识不存在情况下就进行设置 def __delattr__(self, name): try: del self.__storage__[self.__ident_func__()][name] except KeyError: raise AttributeError(name)
__enter__ 和__exit__
用途或者说好处:
1.使用with语句的目的就是把代码块放入with中执行,with结束后,自动完成清理工作,无须手动干预
2.在需要管理一些资源比如文件,网络连接和锁的编程环境中,可以在__exit__中定制自动释放资源的机制,你无须再去关系这个问题,这将大有用处
# __enter__和__exit__ class Foo: def __enter__(self): #with 拿到一个对象,触发enter方法 print('enter') return 11111 def __exit__(self, exc_type, exc_val, exc_tb): #文件打开执行完毕后,执行exit方法 print('exit') print('exc_type',exc_type) #异常的类型 print('exc_val',exc_val) #异常的值 print('exc_tb',exc_tb) #异常的内存地址 return True #清空所有异常,抛异常之后,with后的内容正常执行。 with Foo() as obj: #执行Foo().__enter__方法得到一个返回值,然后将这个值赋给obj。 #出现with语句, 对象的__enter__被触发, 有返回值则赋值给as声明的变量 print('with Foo 的子代码块',obj) #执行with模块字代码 raise NameError('名字没有定义!') #只要是报异常,没有处理的话,就意味着with执行的字代码块运行完。触发exit方法,这之后的代码就不会再执行。 print('##############') print('**************') #执行结果: enter with Foo 的子代码块 11111 exit exc_type <class 'NameError'> exc_val 名字没有定义! exc_tb <traceback object at 0x00000000028EE948> **************
例子:实现上下文的管理协议:(with方法打开文件执行操作!)
class Open: def __init__(self,filepath,mode,encode='utf-8'): self.f=open(filepath,mode=mode,encoding=encode) self.filepath=filepath self.mode=mode self.encoding=encode def write(self,line): print('write') self.f.write(line) def __getattr__(self, item): return getattr(self.f,item) def __enter__(self): #with 对象 就会触发对象下的该方法 return self #将对象返回 write_file=Open('aaaaa.txt','w') #return self.f #这就是返回真实的open方法,字代码块的方法都可以使用,但是就不再是类Open的使用。 def __exit__(self, exc_type, exc_val, exc_tb):#文件结束清理 self.f.close() return True with Open('aaaaa.txt','w') as write_file: #变相的实例化 write_file=Open('aaaaa.txt','w')拿到产生的文件句柄 write_file.write('123123123123123 ') write_file.write('123123123123123 ') write_file.write('123123123123123 ')