2017-02-17 3 views
0

Ich habe eine einfache web.py app, liest eine Konfigurationsdatei und dient URL-Pfaden. Allerdings bekomme ich zwei seltsame Verhaltensweisen. Zum einen werden Änderungen an Daten im Hauptverzeichnis nicht in den Ergebnissen von GET wiedergegeben. Zwei, Main scheint zweimal zu laufen.web.py läuft zweimal, ignoriert Änderungen

Gewünschtes Verhalten ändert Daten in Main wird dazu führen, dass Methoden geänderte Daten sehen und keine Hauptrückläufe haben.

Fragen:

  1. Was hier wirklich geschieht, ist, dass myDict nicht in jedem GET geändert.
  2. Warum bekomme ich Code, der zweimal ausgeführt wird.
  3. Simplest Weg zum gewünschten Verhalten (wichtigste)
  4. Pythonic Weg zum gewünschten Verhalten (unwichtigsten)

Von pbuck (akzeptierte Antwort): Antwort zu 3.) ist ersetzen

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

mit:

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

gleiches Verhalten auf Pythons Linux (CentOS 6 Python 2.6.6) und MacBook (Gebräu Python 2.7.12)

Wann begann ich:

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

Bei einer Abfrage mit:

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

was dazu führt, (man beachte eine zweite "Initialisieren 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() 

Antwort

1

Kurze Antwort, vermeiden Globals verwenden, da sie nicht das tun, was Sie denken, sie tun. Vor allem, wenn Sie dies später unter nginx/apache bereitstellen, wo (wahrscheinlich) mehrere Prozesse ausgeführt werden.

Längere Antwort

  1. Warum bin ich einige Code immer läuft zweimal?

-Code, global app.py, läuft zweimal, weil es einmal läuft, wie es normalerweise der Fall ist. Das zweite Mal ist innerhalb der web.application(urls, globals()) Anruf. Wirklich, dieser Aufruf an globals() richtet Modul laden/neu laden. Ein Teil davon ist das Neuladen aller Module (einschließlich app.py). Wenn Sie autoreload=False in dem Aufruf von web.applications() festlegen, wird es das nicht tun.

  1. Was hier geschieht wirklich, ist, dass myDict in nicht geändert entweder GET?

myDict wird immer zu ‚etwas dynamischer‘ gesetzt, dann aber auf den zweiten Last zu ‚etwas statisch‘ neu eingestellt werden. Setzen Sie wieder autoreload=False und es wird funktionieren, wie Sie es erwarten.

  1. Kürzester Pfad?

autoreload=False

  1. Pythonic Weg?

.... na ja, frage ich mich, warum Sie mydict['somevalue'] = 'something static'undmydict['somevalue'] = 'something dynamic' in Ihrem Modul haben auf diese Weise: warum nicht einfach eingestellt einmal unter '__main__'?

+0

Vielen Dank für Ihre informative Antwort. 1. Es ist nicht Nginx oder Apache, und wird es nie sein, es ist ein kleiner/wichtiger 1 Quellmodul Low Impact Service, also Globals. Als ich zwei von allem sah, dachte ich sofort "fork", aber nein, aber vielleicht hat es einen zweiten Thread. . Es gibt keinen zweiten Prozess, überprüfte ich. 2. Mein Verständnis ist die IF-Anweisung um main soll verhindern, dass es zweimal ausgeführt wird. 3. Ich werde es versuchen. 4. mydict ['somevalue'] wurde im Beispiel nur zweimal gesetzt, um das Problem besser zu veranschaulichen. Ursprünglich habe ich es einmal in Main eingestellt und es kehrte zu NoneType/None zurück. – kmarsh

+0

Ich habe diesen Thread gefunden, der die Antwort auf die "korrekte" Art ist, Daten sicher zu übergeben. http://stackoverflow.com/questions/10683968/arguments-to-web-py-handler-classes Das einzige Problem ... selbst wenn ich dies verwende, vermute ich, dass der Initialisierungscode noch zweimal ausgeführt wird! – kmarsh

+0

BTW, wenn das Standardverhalten von web.py __main__ zweimal ausführen soll, halte ich das pathologisch für falsch. – kmarsh