【问题标题】:Session in python?python中的会话?
【发布时间】:2012-09-12 15:24:51
【问题描述】:

Python 是否有会话功能?

如果是,那么我该如何使用它以及我应该使用哪个库?

【问题讨论】:

  • 您是在询问 Web 框架吗?您使用的是哪个网络框架? Python 有几十个。

标签: python session


【解决方案1】:

这可能是一个老问题,但我遇到了同样的问题,即 Python 中没有内置的会话支持。我写了一个简单的会话处理程序,可能对某人有用:

#!/usr/bin/python
# -*- coding: utf-8 -*-

import tempfile
import hashlib
import os
import time
import random
import errno
import ast
import pprint
import fcntl


class CGISession:

    __sessionfile = ''
    __newid = ''
    __date = ''
    __tmp = ''

    __pid = ''
    __time = ''
    __rand = ''

    __pp = pprint.PrettyPrinter()
    __fs = ''

    def __init__(
        self,
        id=None,
        directory=None,
        hash='md5',
        ):

        if directory is None:
            self.__directory = tempfile.gettempdir()
        else:
            if not os.path.exists(directory):
                try:
                    os.makedirs(directory)
                except OSError, error:
                    if error.errno != errno.EEXIST:
                        raise
            self.__directory = directory

        if hash not in ['md5', 'sha256', 'sha512']:
            self.__hash = 'md5'
        else:
            self.__hash = hash

        if id is None:
            self.__id = self.__genSessionID()
            self.__fs = open(os.path.join(self.__directory,
                             'pycgiession_{0}'.format(self.__id)), 'w')
            fcntl.flock(self.__fs.fileno(), fcntl.LOCK_EX)
            self.__fs.write('{}')
            self.__fs.close()
            self.__sessionfile = os.path.join(self.__directory,
                    'pycgiession_{0}'.format(self.__id))
            os.chmod(self.__sessionfile, 0640)
        else:
            try:
                open(os.path.join(self.__directory,
                     'pycgiession_{0}'.format(os.path.basename(id))),
                     'r').close()
                self.__id = os.path.basename(id)
                self.__sessionfile = os.path.join(self.__directory,
                        'pycgiession_{0}'.format(self.__id))
                os.chmod(self.__sessionfile, 0640)
            except IOError, error:
                if error.errno == errno.ENOENT:
                    self.__id = self.__genSessionID()
                    self.__fs = open(os.path.join(self.__directory,
                            'pycgiession_{0}'.format(self.__id)), 'w')
                    fcntl.flock(self.__fs.fileno(), fcntl.LOCK_EX)
                    self.__fs.write('{}')
                    self.__fs.close()
                    self.__sessionfile = os.path.join(self.__directory,
                            'pycgiession_{0}'.format(self.__id))
                    os.chmod(self.__sessionfile, 0640)
                else:
                    raise

    def __genSessionID(self):

        self.__pid = str(os.getpid())
        self.__time = ''.join(map(str, time.gmtime()[0:]))
        self.__rand = str(random.random())

        if self.__hash == 'sha256':
            sha256 = hashlib.sha256()
            sha256.update(self.__pid)
            sha256.update(self.__time)
            sha256.update(self.__rand)
            self.__newid = sha256.hexdigest()
        elif self.__hash == 'sha512':

            sha512 = hashlib.sha512()
            sha512.update(self.__pid)
            sha512.update(self.__time)
            sha512.update(self.__rand)
            self.__newid = sha512.hexdigest()
        else:

            md5 = hashlib.md5()
            md5.update(self.__pid)
            md5.update(self.__time)
            md5.update(self.__rand)
            self.__newid = md5.hexdigest()

        return self.__newid

    def getID(self):
        return self.__id

    def setParam(self, key, value):

        self.__fs = open(self.__sessionfile, 'r')
        fcntl.flock(self.__fs.fileno(), fcntl.LOCK_EX)
        self.__date = self.__fs.readlines()
        self.__fs.close()

        self.__fs = open(self.__sessionfile, 'w')
        fcntl.flock(self.__fs.fileno(), fcntl.LOCK_EX)
        self.__date = ast.literal_eval(self.__date[0])
        self.__date[key] = value

        self.__fs.write(self.__pp.pformat(self.__date))
        self.__fs.close()

    def getParam(self, key):

        self.__fs = open(self.__sessionfile, 'r')
        fcntl.flock(self.__fs.fileno(), fcntl.LOCK_EX)
        self.__date = self.__fs.readline()
        self.__fs.close()
        self.__date = ast.literal_eval(self.__date)
        try:
            self.__date = self.__date[key]
            return self.__date
        except KeyError:
            return None

    def getAll(self):

        self.__fs = open(self.__sessionfile, 'r')
        fcntl.flock(self.__fs.fileno(), fcntl.LOCK_EX)
        self.__date = self.__fs.readlines()
        self.__fs.close()
        self.__date = ast.literal_eval(self.__date[0])
        return self.__date

    def delParam(self, key):

        self.__fs = open(self.__sessionfile, 'r')
        fcntl.flock(self.__fs.fileno(), fcntl.LOCK_EX)
        self.__date = self.__fs.readlines()
        self.__fs.close()

        self.__fs = open(self.__sessionfile, 'w')
        fcntl.flock(self.__fs.fileno(), fcntl.LOCK_EX)
        self.__date = ast.literal_eval(self.__date[0])

        try:
            del self.__date[key]
        except KeyError:
            pass

        self.__fs.write(self.__pp.pformat(self.__date))
        self.__fs.close()

    def clear(self):

        self.__fs = open(self.__sessionfile, 'w')
        fcntl.flock(self.__fs.fileno(), fcntl.LOCK_EX)
        self.__fs.write('{}')
        self.__fs.close()

    def delete(self):

        os.remove(self.__sessionfile)

例子:

>>> from CGISession import CGISession
>>> session = CGISession()
>>> 
>>> session.getID()
'7e487c3c300126fddbecb37b041d66e3'
>>> 
>>> session.setParam('name','A')
>>> session.setParam('friends',['C','D','E'])
>>> 
>>> session.getParam('name')
'A'
>>> session.getParam('friends')
['C', 'D', 'E']
>>> 
>>> session.delParam('name')
>>> session.delParam('friends')
>>> 
>>> session.getParam('name')
>>> session.delParam('friends')
>>> 
>>> session.delete()
>>>

【讨论】:

    【解决方案2】:

    一些 Python Web 框架确实提供了“会话”的概念。 (当然,Python 语言本身与它无关!-)。

    例如Beaker是一个优秀的支持会话的轻量级WSGI中间件;由于 WSGI 通常是将任何 Python Web 框架与任何 Web 服务器连接起来的最佳方式,当然您总是可以在 WSGI 事务中插入 WSGI 中间件,因此 Beaker(与任何其他 WSGI 中间件一样)非常适用。

    【讨论】:

    • 谢谢...你觉得 mod_python API 怎么样?它在我的应用程序中真的有用吗?其实我想做的是。一个会话变量存储我的登录身份验证值,并在执行任何其他脚本之前传递该值。我的脚本只是被称为包装脚本...希望我解释得很好,你明白我想知道什么?
    • @Rahul,我认为 WSGI 比 mod_python 好得多:它不会将您绑定到单个 Web 服务器,并允许您“插入”许多有用的中间件模块——包括关于身份验证的模块以及其他关于会话的人; 非常模块化和灵活——您仍然可以完全独立地选择您喜欢的服务器什么框架。
    • 是的,我今天不会将 mod_python 用于任何事情......太多的锁定。 WSGI 是它所在的地方,而 mod_wsgi 是一个很好、快速的实现。
    【解决方案3】:

    Beaker 在依赖 WSGI 的 Python Web 应用程序中非常流行,但您必须了解 Python 是一种通用编程语言,它不像 PHP 那样 100% 面向 Web。

    如果您列出有关您需要的应​​用程序的更多信息也会有所帮助。

    【讨论】:

      猜你喜欢
      • 2016-06-06
      • 1970-01-01
      • 2010-10-23
      • 1970-01-01
      • 1970-01-01
      • 2020-06-06
      • 2021-09-16
      • 2017-10-16
      • 1970-01-01
      相关资源
      最近更新 更多