了解Python WSGI应用程序中的全局对象持久性

Yar*_*rin 12 python google-app-engine wsgi webapp2

请考虑我在Google App Engine中的WebApp2应用程序中的以下代码:

count = 0

class MyHandler(webapp2.RequestHandler):

    def get(self):

        global count
        count = count + 1
        print count
Run Code Online (Sandbox Code Playgroud)

每次刷新页面时,计数都会增加.

我来自PHP世界,每个请求都是一个新的全球环境.我在这里理解的是,因为我正在使用WebApp2的wsgi配置,所以Python不会对每个请求启动新进程.另一方面,如果我使用cgi配置,全局环境将每次重新实例化,如PHP ...

假设以上是正确的(如果没有,请纠正我)...

  1. 我怎么能处理我想要一个仅在请求的生命周期内持久化的全局变量的场景?我可以在RequestHandler类中放置一个实例变量,但是我导入的实用程序模块如何使用全局变量来存储消息对象呢?
  2. 是否有某种技术可以重置所有变量,或强制重新实例化环境?
  3. 全球环境是否会无限期地持续存在,还是会在某个时刻自行重置?
  4. 这个GAE是否具体,或者wsgi全局持久性在任何服务器场景中都是一样的吗?

编辑:

这是使用threadlocal的尝试:

count = 0

mydata = threading.local()
mydata.count = 0

class MyHandler(webapp2.RequestHandler):

    def get(self):

        global count
        count = count + 1
        print count

        mydata.count = mydata.count + 1
        print mydata.count
Run Code Online (Sandbox Code Playgroud)

这些也会在请求之间递增

Nic*_*son 16

你的理解是正确的.如果您希望变量在请求期间持续存在,则不应将它们设为全局变量 - 在RequestHandler类中创建实例变量,访问为self.var.由于为每个请求实例化了一个新的RequestHandler,因此只要您需要它们,您的变量就会保持不变.除非您确实需要全局(而不是特定于请求)范围,否则最好避免使用全局变量.

另请注意,您的App Engine应用程序将在多个服务器上运行; 只有同一服务器内的请求才能访问全局变量.

  • 关于多个服务器的好处 - 谢谢 (3认同)

Mic*_*kel 5

您对情况的分析是正确的,Python Web 应用程序是一个长期运行的过程。启动 Python 解释器需要很长时间,并且并不是每个请求都完成。

完全有可能创建一个“每个请求”不同的全局变量。很多框架都这样做了,人们似乎很喜欢它。执行此操作的方法取决于服务器。大多数服务器使用“每个请求一个线程”,我认为 GAE 也是如此。如果是这种情况,您可以使用线程局部变量。如果您担心该值会在该线程上的请求之间保留,那么您将需要一些可以挂钩请求的开始/结束的管理代码。如果 WebApp2 框架没有提供一个好的方法来做到这一点,那么 WSGI 中间件是一个好地方。

它只是 Python,请求是在它自己的线程中提供的。从那里你可以做你想做的事。Python 中没有任何东西可以重置所有全局变量,并且通常不能保证(尤其是 GAE)为您的请求提供服务的进程每次都是同一个进程,这意味着您的全局变量不应该用于在请求之间保留数据,除非您真正知道你在做什么。

有许多框架已经为执行此操作提供了良好的支持,因此如果 WebApp2 没有那么我建议您寻找其他地方。Python 有很多选项,其中许多都可以在 GAE 上运行。