zoukankan      html  css  js  c++  java
  • flask0.1版本源码浅析——Request

    4 请求(request)

    from flask import request

    request接收了WSGI server 传递过来的 environ 字典变量,并提供了很多常用的属性和方法可以使用,比如请求的 method、path、args 等。

    同时request还有一个特性——它不能被应用修改,应用只能读取请求的数据。

    ---> 4.1 Request(RequestBase)

    其中 from werkzeug.wrappers import Request as RequestBase

    该类继承 werkzeug的 request后,定义了一些 @property属性

      ---> werkzeug.wrappers:Request

    class Request(BaseRequest, AcceptMixin, ETagRequestMixin,
                  UserAgentMixin, AuthorizationMixin,
                  CommonRequestDescriptorsMixin):
    
        """Full featured request object implementing the following mixins:
    
        - :class:`AcceptMixin` for accept header parsing
        - :class:`ETagRequestMixin` for etag and cache control handling
        - :class:`UserAgentMixin` for user agent introspection
        - :class:`AuthorizationMixin` for http auth handling
        - :class:`CommonRequestDescriptorsMixin` for common headers
        """
    View Code

        ---> BaseRequest

    class BaseRequest(object):
        def __init__(self, environ, populate_request=True, shallow=False):
            self.environ = environ
            if populate_request and not shallow:
                self.environ['werkzeug.request'] = self
            self.shallow = shallow
        主要就是传入了 self.environ 作为字段。
        然后用 @cached_property 定义了一些属性, 像 args, form, cookies等等
    ---> cached_property
    接下来我们看看 增强版的 property
    class cached_property(property):
    
        """A decorator that converts a function into a lazy property.  The
        function wrapped is called the first time to retrieve the result
        and then that calculated result is used the next time you access
        the value.
    
        The class has to have a `__dict__` in order for this property to
        work.
        """
    
        # implementation detail: A subclass of python's builtin property
        # decorator, we override __get__ to check for a cached value. If one
        # choses to invoke __get__ by hand the property will still work as
        # expected because the lookup logic is replicated in __get__ for
        # manual invocation.
    
        def __init__(self, func, name=None, doc=None):
            self.__name__ = name or func.__name__
            self.__module__ = func.__module__
            self.__doc__ = doc or func.__doc__
            self.func = func
    
        def __set__(self, obj, value):
            obj.__dict__[self.__name__] = value
    
        def __get__(self, obj, type=None):
            if obj is None:
                return self
            value = obj.__dict__.get(self.__name__, _missing)
            if value is _missing:
                value = self.func(obj)
                obj.__dict__[self.__name__] = value
            return value
    View Code

    这个装饰器同时也是实现了 __set__ 和 __get__ 方法的描述器。 访问它装饰的属性,就会调用 __get__ 方法,这个方法先在 obj.__dict__ 中寻找是否已经存在对应的值。如果存在,就直接返回;如果不存在,调用底层的函数 self.func,并把得到的值保存起来,再返回。这也是它能实现缓存的原因:因为它会把函数的值作为属性保存到对象中。 ---cizixs

     
  • 相关阅读:
    Spring Boot 2 (十):Spring Boot 中的响应式编程和 WebFlux 入门
    开源精神就意味着免费吗?
    是时候给大家介绍 Spring Boot/Cloud 背后豪华的研发团队了。
    springcloud(十五):Spring Cloud 终于按捺不住推出了自己的服务网关 Gateway
    写年终总结到底有没有意义?
    培训班出来的怎么了?
    【重磅】Spring Boot 2.1.0 权威发布
    一线大厂逃离或为新常态,大龄程序员改如何选择?
    Elastic 今日在纽交所上市,股价最高暴涨122%。
    技术人如何搭建自己的技术博客
  • 原文地址:https://www.cnblogs.com/fuzzier/p/7500593.html
Copyright © 2011-2022 走看看