web.py running main twice, ignoring changes

守給你的承諾、 提交于 2020-01-06 18:06:15

问题


I have a simple web.py app that reads a config file and serves to URL paths. However I get two strange behaviors. One, changes made to data in the Main are not reflected in the results of GET. Two, Main appears to run twice.

Desired behavior is modifying data in Main will cause methods to see modified data, and not having main re-run.

Questions:

  1. What is really happening here, that mydict is not modified in either GET.
  2. Why am I getting some code running twice.
  3. Simplest path to desired behavior (most important)
  4. Pythonic path to desired behavior (least important)

From pbuck (Accepted Answer): Answer for 3.) is replace

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

with:

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

Same behavior on pythons Linux (CentOS 6 python 2.6.6) and MacBook (brew python 2.7.12)

When started I get:

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

When queried with:

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

Which results in (notice a second "Initializing 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

Code:

#!/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()

回答1:


Short answer, avoid using globals as they don't do what you think they do. Especially when you eventually deploy this under nginx / apache where there will (likely) be multiple processes running.

Longer answer

  1. Why am I getting some code running twice?

Code, global to app.py, is running twice because it runs once, as it normally does. The second time is within the web.application(urls, globals()) call. Really, that call to globals() sets up module loading / re-loading. Part of that is re-loading all modules (including app.py). If you set autoreload=False in the web.applications() call, it won't do that.

  1. What is really happening here, that mydict is not modified in either GET?

mydict is getting set to 'something dynamic', but then being re-set to 'something static' on second load. Again, set autoreload=False and it will work as you expect.

  1. Shortest path?

autoreload=False

  1. Pythonic path?

.... well, I wonder why you have mydict['somevalue'] = 'something static' and mydict['somevalue'] = 'something dynamic' in your module this way: why not just set it once under '__main__'?



来源:https://stackoverflow.com/questions/42305098/web-py-running-main-twice-ignoring-changes

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!