关于Flask session实现的一些疑惑与思考

疑惑

  用过Flask的人应该都知道session。

  刚接触时,我有些疑惑,为什么Flask的session可以使用如下的一些方法?

  1. session.username = '' # 将键值存进session

  2. session['username'] = [] # 同上

  3. del session['usernmae'] # 删除session中存储的键值

  4. session.pop('username') # 同上

    从源码可以看出 flask 的 session 是一个 LocalProxy class 的实例,这是werkzueg中的一个class。

    一般的类可 “都没有” 这些方法和语法。

    如果你和当时的我有着相同的疑问,希望接下来的一些文字可以解答你的疑惑。

思考

  从源码可以看出LocalProxy使用了__slot__, __setitem__, __delitem__等一些变量和方法,

  部分方法属于内置的Magic method,都可以在Python官方文档找到。

  接下来会使用一些Magic method实现文首的四种session操作。

注:Python 中的 Magic 方法是将“ Magic”添加到类中的特殊方法。 Magic方法并不意味着可以直接调用,
但是调用是在类内部对某个动作进行的。 例如,当使用 + 运算符将两个数字相加时,将在内部调用 __add__ ()方法,
有人可能想起了C++的重载运算符。

简易code实现

class MyClass(object):
    # 允许使用`class.a`设置新的属性a
    __slot__ = "__dict__"
            
    def __setitem__(self, key, value):
        '''
        允许类使用中括号`class['a'] = vlaue`设置属性a。
        '''
        self.__dict__[key] = value

    def __delitem__(self, key):
        '''
        允许类使用`del class.a`删除属性a。
        '''
        del self.__dict__[key]
    
    def __getitem__(self, key):
        '''
        允许类使用`class['a']`获取属性a的值。
        '''
        try:
            return self.__getattribute__(key)
        except AttributeError:
            raise AttributeError(key)
    
    def pop(self, key):
        '''
        以class.pop('a')删除属性a。
        '''
        try:
            return self.__dict__.pop(key)
        except KeyError:
            raise KeyError(key)


session = MyClass()
session['username'] = 'coodyz'
session.role = 'admin'
print(session.__dict__)
# {'username': 'coodyz', 'role': 'admin'}
del session['username']
print(session.__dict__)
# {'role': 'admin'}
session.pop('role')
print(session.__dict__)
# {}

posted @ 2020-06-26 17:33  Coodyzのblog  阅读(231)  评论(0编辑  收藏  举报