【问题标题】:web.py running main twice, ignoring changesweb.py 运行 main 两次,忽略更改
【发布时间】:2017-07-07 09:40:08
【问题描述】:

我有一个简单的 web.py 应用程序,它读取配置文件并提供给 URL 路径。但是我得到了两种奇怪的行为。一、对 Main 中的数据所做的更改不会反映在 GET 的结果中。二,Main 似乎运行了两次。

期望的行为是修改 Main 中的数据将导致方法看到修改后的数据,并且没有 main 重新运行。

问题:

  1. 这里真正发生的事情是,mydict 都没有被修改 得到。
  2. 为什么我的一些代码运行了两次。
  3. 实现所需行为的最简单途径(最重要)
  4. 所需行为的 Pythonic 路径(最不重要)

来自 pbuck(已接受的答案):3.)的答案是替换

app = web.application(urls, globals())

与:

app = web.application(urls, globals(), autoreload=False)

在 pythons Linux (CentOS 6 python 2.6.6) 和 MacBook (brew python 2.7.12) 上的行为相同

开始时我得到:

$ python ./foo.py 8080
Initializing mydict
Modifying mydict
http://0.0.0.0:8080/

查询时:

wget http://localhost:8080/node/first/foo
wget http://localhost:8080/node/second/bar

这会导致(注意第二个“初始化 mydict”):

Initializing mydict
firstClass.GET called with clobber foo
firstClass.GET somevalue is something static
127.0.0.1:52480 - - [17/Feb/2017 17:30:42] "HTTP/1.1 GET /node/first/foo" - 200 OK
secondClass.GET called with clobber bar
secondClass.GET somevalue is something static
127.0.0.1:52486 - - [17/Feb/2017 17:30:47] "HTTP/1.1 GET /node/second/bar" - 200 OK

代码:

#!/usr/bin/python
import web

urls = (
    '/node/first/(.*)', 'firstClass',
    '/node/second/(.*)', 'secondClass'
    )

# Initialize web server, start it later at "app . run ()"
#app = web.application(urls, globals())
# Running web.application in Main or above does not change behavior

# Static Initialize mydict
print "Initializing mydict"
mydict = {}
mydict['somevalue'] = "something static"

class firstClass:
    def GET(self, globarg):
        print "firstClass.GET called with clobber %s" % globarg
        print "firstClass.GET somevalue is %s" % mydict['somevalue']
        return mydict['somevalue']

class secondClass:
    def GET(self, globarg):
        print "secondClass.GET called with clobber %s" % globarg
        print "secondClass.GET somevalue is %s" % mydict['somevalue']
        return mydict['somevalue']

if __name__ == '__main__':
    app = web.application(urls, globals())
    # read configuration files for initializations here
    print "Modifying mydict"
    mydict['somevalue'] = "something dynamic"
    app.run()

【问题讨论】:

    标签: python-2.7 web.py


    【解决方案1】:

    简短的回答,避免使用全局变量,因为它们不会像您认为的那样做。尤其是当您最终将其部署在 nginx / apache 下时(可能)会有多个进程在运行。

    更长的答案

    1. 为什么某些代码会运行两次?

    app.py 的全局代码运行两次,因为它运行一次,就像它通常那样。第二次是在web.application(urls, globals()) 通话中。确实,对globals() 的调用设置了模块加载/重新加载。其中一部分是重新加载所有模块(包括 app.py)。如果你在 web.applications() 调用中设置autoreload=False,它不会那样做。

    1. 这里到底发生了什么,mydict 没有在任何一个 GET 中修改?

    mydict 被设置为“动态”,但在第二次加载时被重新设置为“静态”。再次设置autoreload=False,它将按您的预期工作。

    1. 最短路径?

    autoreload=False

    1. Python 路径?

    ....好吧,我想知道为什么你的模块中有mydict['somevalue'] = 'something static' mydict['somevalue'] = 'something dynamic' 这样:为什么不在'__main__' 下设置一次?

    【讨论】:

    • 感谢您提供的信息丰富的回答。 1. 它不是 nginx 或 apache,也永远不会是,它是一个小型/重要的 1 源模块低影响服务,因此是全局的。当我看到其中的两个时,我立即想到了“fork”,但没有,但也许它有第二个线程。 .没有第二个过程,我检查了。 2.我的理解是main周围的IF语句应该防止它运行两次。 3. 我会试试的。 4. mydict['somevalue'] 在示例中设置了两次,只是为了更好地说明问题。最初我在 Main 中设置了一次,然后它恢复为 NoneType/None。
    • 我找到了这个线程,这似乎是安全传递数据的“正确”方式的答案。 stackoverflow.com/questions/10683968/…唯一的问题……即使我用这个,我怀疑初始化代码还是会运行两次!
    • 顺便说一句,如果 web.py 的默认行为是运行 main 两次,我认为这是病态的错误。
    • 第二次加载app.py__name__ 设置为__app__,而不是__main__,所以这是在第一次或第二次加载时发生或不发生某些事情的一种方法.
    • autoreload=False 效果很好。修复了这两个问题,运行两次并重置值。接下来将查看 web.config 存储对象以替换全局变量。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-19
    相关资源
    最近更新 更多