WERKZEUG中utils模块

utils是一个工具模块,很多方法都用在responserequest模块中。当设计中间件的时候也需要调用某些方法。

第一个类,是一个自定义的描述符类,重构了property方法,用法相当于@property,可以参考geek范

class cached_property(property):
    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                                                             #设置__name__属性的值

    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                                                                                                       #获取一个实例的__name__属性,这里注意取值是obj.__dict__get().不能用self.__name__

描述的get方法,如果是属性取得属性的值,如果是返回的函数,就返回函数的地址。

class Person():
    def __get__(self,attr):
        if attr=='name':
            return lambda:'hyperion'
s=Person()
print s.name()

上述代码返回的函数,所以需要用函数调用符号调用才能打印处函数返回值。如果不调用只能打印函数的地址。

下面分析一下HTMLBuild

class HTMLBuilder(object):
    
    def __init__(self, dialect):
        self._dialect = dialect

    def __call__(self, s):
        return escape(s)

    def __getattr__(self, tag):
        if tag[:2] == '__':
            raise AttributeError(tag)

        def proxy(*children, **arguments):
            buffer = '<' + tag
            for key, value in iteritems(arguments):
                if value is None:
                    continue
                if key[-1] == '_':
                    key = key[:-1]
                if key in self._boolean_attributes:
                    if not value:
                        continue
                    if self._dialect == 'xhtml':
                        value = '="' + key + '"'
                    else:
                        value = ''
                else:
                    value = '="' + escape(value) + '"'
                buffer += ' ' + key + value
            if not children and tag in self._empty_elements:
                if self._dialect == 'xhtml':
                    buffer += ' />'
                else:
                    buffer += '>'
                return buffer
            buffer += '>'

            children_as_string = ''.join([text_type(x) for x in children
                                          if x is not None])

            if children_as_string:
                if tag in self._plaintext_elements:
                    children_as_string = escape(children_as_string)
                elif tag in self._c_like_cdata and self._dialect == 'xhtml':
                    children_as_string = '/*<![CDATA[*/' + 
                                         children_as_string + '/*]]>*/'
            buffer += children_as_string + '</' + tag + '>'
            return buffer
        return proxy

上面定义的_getattr就是返回一个函数,html = HTMLBuilder('html')实例化,接着html.p()就可以调用getattr中返回的函数。

接下来就是用得比较多的redirect方法:

def redirect(location, code=302, Response=None):
    if Response is None:
        from werkzeug.wrappers import Response

    display_location = escape(location)
    if isinstance(location, text_type):
        from werkzeug.urls import iri_to_uri
        location = iri_to_uri(location, safe_conversion=True)                   #将路径转换成uri
    response = Response(
        '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
'
        '<title>Redirecting...</title>
'
        '<h1>Redirecting...</h1>
'
        '<p>You should be redirected automatically to target URL: '
        '<a href="%s">%s</a>.  If not click the link.' %
        (escape(location), display_location), code, mimetype='text/html')                                                          #调用响应response
    response.headers['Location'] = location
    return response

除了以上方法,还有针对模块调用的方法,以及参数认证的方法。用于在运行时确认的方法。

原文地址:https://www.cnblogs.com/hyperionworld/p/5373139.html