疑惑
用过Flask的人应该都知道session。
刚接触时,我有些疑惑,为什么Flask的session可以使用如下的一些方法?
-
session.username = '' # 将键值存进session
-
session['username'] = [] # 同上
-
del session['usernmae'] # 删除session中存储的键值
-
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__)
# {}