I use the built-in webserver from web.py and not apache like in this question: Global variable usage with web.py in Apache
I have this web service that takes a number as argument, adds it to an internal variable number
and returns that variable.
Here's how the script looks like:
import web
import sys
urls = (
'/(\d+)', 'Number'
)
class Number:
def GET(self, parameter):
# I want to read and write to the variable number here
print "number in web service is " + str(number)
number = number + int(parameter)
return number
if __name__ == "__main__":
#print sys.argv
# I want to initialise the variable number here, based on command line parameter
number = int(sys.argv[2]) if len(sys.argv) >= 3 else 0 # initialisation
print "number init value " + str(number)
app = web.application(urls, globals())
app.run()
I start the server like so:
sudo python test.py 192.168.0.100 16
Where 16
is the initial value for the internal counter.
When executed like so:
http://192.168.0.100:8080/42
I get an UnboundLocalError: local variable 'number' referenced before assignment
on this line
print "number in web service is " + str(number)
Ok, so I need global
, because I don't want number
to be a local variable of the service, I change to:
import web
import sys
urls = (
'/(\d+)', 'Number'
)
class Number:
def GET(self, parameter):
# I want to read and write to the variable number here
global number # number is not a lcoal variable
print "number in web service is " + str(number)
number = number + int(parameter)
return number
if __name__ == "__main__":
#print sys.argv
# I want to initialise the variable number here, based on command line parameter
number = int(sys.argv[2]) if len(sys.argv) >= 3 else 0 # initialisation
print "number init value " + str(number)
app = web.application(urls, globals())
app.run()
Now I get a different error when calling the service on the same line NameError: global name 'number' is not defined
. To fix this, I add an initialization at the top:
import web
import sys
urls = (
'/(\d+)', 'Number'
)
number = 0 # assigning value to define variable
class Number:
def GET(self, parameter):
# I want to read and write to the variable number here
global number # number is not a lcoal variable
print "number in web service is " + str(number)
number = number + int(parameter)
return number
if __name__ == "__main__":
#print sys.argv
# I want to initialise the variable number here, based on command line parameter
number = int(sys.argv[2]) if len(sys.argv) >= 3 else 0 # initialisation
print "number init value " + str(number)
app = web.application(urls, globals())
app.run()
While I do not receive an error now, the logic is broken. While the initial print displays that number init value is 16
, the other print does not have the same value, it says number in web service is 0
.
Apparently, there are two separate number
variables in my code. I found this answer that states that __main__
is a separate module. Now that explains the different values for number
. However, when I try to add global
to __main__
, like so:
import web
import sys
urls = (
'/(\d+)', 'Number'
)
number = 0 # assigning value to define variable
class Number:
def GET(self, parameter):
# I want to read and write to the variable number here
global number # number is not a lcoal variable
print "number in web service is " + str(number)
number = number + int(parameter)
return number
if __name__ == "__main__":
#print sys.argv
# I want to initialise the variable number here, based on command line parameter
global number # I want that one global variable number
number = int(sys.argv[2]) if len(sys.argv) >= 3 else 0 # initialisation
print "number init value " + str(number)
app = web.application(urls, globals())
app.run()
The value is again 16 upon initialization and 0 on the service.
I get a SyntaxWarning: name 'number' is assigned to before global declaration
on that new line in __main__
So I got rid of the assignment on the top again, which wasn't really necessary in the first place. because the real initialization happens in __main__
:
import web
import sys
urls = (
'/(\d+)', 'Number'
)
class Number:
def GET(self, parameter):
# I want to read and write to the variable number here
global number # number is not a lcoal variable
print "number in web service is " + str(number)
number = number + int(parameter)
return number
if __name__ == "__main__":
#print sys.argv
# I want to initialise the variable number here, based on command line parameter
global number # I want that one global variable number
number = int(sys.argv[2]) if len(sys.argv) >= 3 else 0 # initialisation
print "number init value " + str(number)
app = web.application(urls, globals())
app.run()
While that executes without warnings initially, I do get a NameError global name 'number' is not defined
from the GET
method.
How do I create a variable that I can set in __main__
and that I can also read and write to from a method of a class that's defined in the same file?