码迷,mamicode.com
首页 > 其他好文 > 详细

面向对象中有哪些双下线方法及应用场景

时间:2020-07-04 20:52:05      阅读:20      评论:0      收藏:0      [点我收藏+]

标签:erro   package   att   lse   cep   serialize   sts   nal   ase   

如下:

#(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__
#(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对象

#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)

 

面向对象中有哪些双下线方法及应用场景

标签:erro   package   att   lse   cep   serialize   sts   nal   ase   

原文地址:https://www.cnblogs.com/zh-xiaoyuan/p/13236216.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有 京ICP备13008772号-2
迷上了代码!