zoukankan      html  css  js  c++  java
  • Python 元类

    http://ningning.today/2017/01/25/python/simple-python-metaclass/

    https://stackoverflow.com/questions/25221072/how-to-write-a-python-abc-with-a-concrete-initializer-in-python-2-6-to-3-5

    具体操作例子

    查看Flask-restful源码views.py文件

    class View(object):
        """Alternative way to use view functions.  A subclass has to implement
        :meth:`dispatch_request` which is called with the view arguments from
        the URL routing system.  If :attr:`methods` is provided the methods
        do not have to be passed to the :meth:`~flask.Flask.add_url_rule`
        method explicitly::
    
            class MyView(View):
                methods = ['GET']
    
                def dispatch_request(self, name):
                    return 'Hello %s!' % name
    
            app.add_url_rule('/hello/<name>', view_func=MyView.as_view('myview'))
    
        When you want to decorate a pluggable view you will have to either do that
        when the view function is created (by wrapping the return value of
        :meth:`as_view`) or you can use the :attr:`decorators` attribute::
    
            class SecretView(View):
                methods = ['GET']
                decorators = [superuser_required]
    
                def dispatch_request(self):
                    ...
    
        The decorators stored in the decorators list are applied one after another
        when the view function is created.  Note that you can *not* use the class
        based decorators since those would decorate the view class and not the
        generated view function!
        """
    
        #: A list of methods this view can handle.
        methods = None
    
        #: The canonical way to decorate class-based views is to decorate the
        #: return value of as_view().  However since this moves parts of the
        #: logic from the class declaration to the place where it's hooked
        #: into the routing system.
        #:
        #: You can place one or more decorators in this list and whenever the
        #: view function is created the result is automatically decorated.
        #:
        #: .. versionadded:: 0.8
        decorators = ()
    
        def dispatch_request(self):
            """Subclasses have to override this method to implement the
            actual view function code.  This method is called with all
            the arguments from the URL rule.
            """
            raise NotImplementedError()
    
        @classmethod
        def as_view(cls, name, *class_args, **class_kwargs):
            """Converts the class into an actual view function that can be used
            with the routing system.  Internally this generates a function on the
            fly which will instantiate the :class:`View` on each request and call
            the :meth:`dispatch_request` method on it.
    
            The arguments passed to :meth:`as_view` are forwarded to the
            constructor of the class.
            """
            def view(*args, **kwargs):
                self = view.view_class(*class_args, **class_kwargs)
                return self.dispatch_request(*args, **kwargs)
    
            if cls.decorators:
                view.__name__ = name
                view.__module__ = cls.__module__
                for decorator in cls.decorators:
                    view = decorator(view)
    
            # We attach the view class to the view function for two reasons:
            # first of all it allows us to easily figure out what class-based
            # view this thing came from, secondly it's also used for instantiating
            # the view class so you can actually replace it with something else
            # for testing purposes and debugging.
            view.view_class = cls
            view.__name__ = name
            view.__doc__ = cls.__doc__
            view.__module__ = cls.__module__
            view.methods = cls.methods
            return view
    
    
    class MethodViewType(type):
    
        def __new__(cls, name, bases, d):
            rv = type.__new__(cls, name, bases, d)
            if 'methods' not in d:
                methods = set(rv.methods or [])
                for key in d:
                    if key in http_method_funcs:
                        methods.add(key.upper())
                # If we have no method at all in there we don't want to
                # add a method list.  (This is for instance the case for
                # the base class or another subclass of a base method view
                # that does not introduce new methods).
                if methods:
                    rv.methods = sorted(methods)
            return rv
    
    
    class MethodView(with_metaclass(MethodViewType, View)):
        """Like a regular class-based view but that dispatches requests to
        particular methods.  For instance if you implement a method called
        :meth:`get` it means it will respond to ``'GET'`` requests and
        the :meth:`dispatch_request` implementation will automatically
        forward your request to that.  Also :attr:`options` is set for you
        automatically::
    
            class CounterAPI(MethodView):
    
                def get(self):
                    return session.get('counter', 0)
    
                def post(self):
                    session['counter'] = session.get('counter', 0) + 1
                    return 'OK'
    
            app.add_url_rule('/counter', view_func=CounterAPI.as_view('counter'))
        """
        def dispatch_request(self, *args, **kwargs):
            meth = getattr(self, request.method.lower(), None)
            # If the request method is HEAD and we don't have a handler for it
            # retry with GET.
            if meth is None and request.method == 'HEAD':
                meth = getattr(self, 'get', None)
            assert meth is not None, 'Unimplemented method %r' % request.method
            return meth(*args, **kwargs)
    
  • 相关阅读:
    VB已死?还是会在Roslyn之下焕发新生?
    GitHub在Visual Studio 2015中获得TFS/VSO同等地位
    单体应用与微服务优缺点辨析
    对于JavaScript的函数.NET开发人员应该知道的11件事
    TypeScript 1.5 Beta带来修饰元数据支持
    Visual Studio 2015 RC中的ASP.NET新特性和问题修正
    Visual Studio从此走入非Windows程序猿家
    Azure DocumentDB对比MongoDB
    正确理解DTO、值对象和POCO
    大数据技术之_19_Spark学习_05_Spark GraphX 应用解析小结
  • 原文地址:https://www.cnblogs.com/schangech/p/7815038.html
Copyright © 2011-2022 走看看