django module-level cache - python

I am trying to store a value in a module level variable for later retrieval.
This function when called with a GET method throws this error: local variable 'ICS_CACHE' referenced before assignment
What am I doing wrong here?
ICS_CACHE = None
def ical_feed(request):
if request.method == "POST":
response = HttpResponse(request.POST['file_contents'], content_type='text/calendar')
response['Content-Disposition'] = 'attachment; filename=%s' % request.POST['file_name']
ICS_CACHE = response
return response
elif request.method == "GET":
return ICS_CACHE
raise Http404
I constructed a basic example to see if a function can read module constants and it works just fine:
x = 5
def f():
print x
f()
---> "5"

Add
global ISC_CACHE
as the first line of your function. You are assigning to it inside the function body, so python assumes that it is a local variable. As a local variable, though, you can't return it without assigning to it first.
The global statement lets the parser know that the variable comes from outside of the function scope, so that you can return its value.
In response to your second posted example, what you have shows how the parser deals with global variables when you don't try to assign to them.
This might make it more clear:
x = 5 # global scope
def f():
print x # This must be global, since it is never assigned in this function
>>> f()
5
def g():
x = 6 # This is a local variable, since we're assigning to it here
print x
>>> g()
6
def h():
print x # Python will parse this as a local variable, since it is assigned to below
x = 7
>>> h()
UnboundLocalError: local variable 'x' referenced before assignment
def i():
global x # Now we're making this a global variable, explicitly
print x
x = 8 # This is the global x, too
>>> x # Print the global x
5
>>> i()
5
>>> x # What is the global x now?
8

Related

How to change value of global variable in a function?

I got a code from the internet for my project, and there is a function with parameter that i need to make change of global variable value
it is a flask request json app, i use the ifttt to send json to this project. i've tried to change by this code but it won't change, the X always in 1
X=1
#app.route('/',methods=['POST'])
def index():
req = request.get_json(silent=True, force=True)
val = processRequest(req)
#print(val)
r = make_response(json.dumps(val))
r.headers['Content-Type'] = 'application/json'
return r
def processRequest(req):
device = req['device']
state = json.loads(req['state'])
#print(state)
if (device=='bedlamp'):
global()['X']=int(30)
i want it when the ifttt send device bedlamp, the value of global variable turn to 30, can anybody help me?
To change a global variable called X inside a function you have to do:
1) bring the variable into the function scope
global X
2) change its value
X = 30
so:
def abc():
global x
x = 30
You need to use the global keyword, like this:
def processRequest(req):
device = req['device']
state = json.loads(req['state'])
if (device=='bedlamp'):
global X
X = 30

Python how to reference variable

I'm getting a problem when referencing variables on a python file. Here is the code:
FG_E = 9
FG_R = 8
START = 7
READY = 9
MC = 3
BRAKE = 5
ERROR = 6
a = 2
b = 3
position = 0
def build_message(signal):
message = position
message = message | (0b1<<signal)
s = bin(message)
s = s[2:len(s)]
s = (16-len(s))*'0' + s
s0 = s[0:len(s)/2]
s1 = s[len(s)/2:len(s)]
s0 = s0[::-1]
s1 = s1[::-1]
s_final = int(s0 + s1, 2)
position = s_final
print bin(s_final)
return s_final
build_message(FG_R)
The error I get is:
UnboundLocalError: local variable 'position' referenced berofe assigment
The problematic line is actually position = s_final in the function build_message.
If it wasn't there then message = position would work because the Python interpreter would know to which position variable you are referring.
But in this case it is ambiguous because you're are later reassigning to position (position = s_final).
You should either re think the design of the code, or add global position as the first line in build_message. Keep in mind that as it says, it would make position a global variable and build_message will change the value of position every where throughout your code.
EDIT A quick demo:
global_var = 0
def foo1():
print(global_var)
def foo2():
print(global_var)
global_var = 1
def foo3():
global global_var
print(global_var)
global_var = 1
print(global_var)
foo1()
>> 0
foo2()
>> UnboundLocalError: local variable 'global_var' referenced before assignment
foo3()
>> 0
1
You need to use global keyword to access global variable.
def build_message(signal):
global position
message = position
If you are using an outside variable into a function maybe you should consider passing it as an argument, like:
def build_message(signal,position):
pass

Why does function only return var if I make it global?

Why does the first function 'define_vartest' not return the var as expected. Not until I make it global (the second function 'define_vartest_global'), does it work. And what is the difference between returning a var at the end of a function and defining a global var within same function??? I am puzzled.
def define_vartest():
vartest = 1
return vartest
def define_vartest_global():
global vartest_global
vartest_global = 1
return vartest_global
define_vartest()
define_vartest_global()
#print('vartest', vartest)
print('vartest_global', vartest_global)
Basically - if I remove the rem from the print vartest line the script stops. Why does the var not get defined, as I return it from the function?
Please explain
Answered below.
This code works as expected. Thanks
def define_vartest():
vartest = 1
return vartest
def define_vartest_global():
global vartest_global
vartest_global = 1
return vartest_global
vartest = define_vartest()
vartest_global = define_vartest_global()
print('vartest', vartest)
print('vartest_global', vartest_global)
You must assign the value you return:
def define_vartest():
vartest = 1
return vartest
vartest = define_vartest()
print('vartest', vartest)
Otherwise the print statement will be unable to see it, because they are in different scope.
This mean that vartest inside the function and vartest outside are different variables. With the return you give the value of the vartest inside to the vartest outside.
Because you never read the returned value. Think about this:
def foo():
return 1
foo()
What is going to happen with the 1? It's lost since no one cares. You need to save it in a new variable to keep it:
def foo():
return 1
vartest = foo()
Now let's add a local variable:
def foo():
a = 1
return a
b = foo() # assign the result of the function call to "b"
# "a" is undefined since it's local to "foo"
print('b',b)
This effect is called "scoping". Each variable has a "scope", a kind of horizon within which it is visible. It's not visible outside. That way, you can reuse names in different functions.

Python: Print a function which returned a value without running the function

If I try to run the following code:
def func():
a = 5
print 'done'
return a
temp = raw_input('')
if temp == '':
func()
print func()
Say temp is '' and the function is run. It prints done and returns variable a. How can I print the returned variable without running the function once more, so done isn't printed again?
You should assign the returned value to a variable (e.g. a).
Update: you could either print inside the function (version1) or use global variable (version2)
def func():
a = 5
print 'done'
return a
# version 1: if print doesn't have to be outside of the function
def main():
temp = raw_input('')
if temp == '':
local_a = func()
else:
# use else to avoid UnboundLocalError: local variable 'a' referenced
# before assignment
local_a = None
print local_a
if __name__ == "__main__":
main()
# # version 2: if print have to be outside of the function, then I can only
# # think of using global variable, but it's bad.
# global_a = None
# def main():
# temp = raw_input('')
# if temp == '':
# global global_a
# global_a = func()
# if __name__ == "__main__":
# main()
# print global_a
You could use #zyxue's answer above and store the return value to a variable or you could also just not return anything from the function and just assign you final value in a function to a global variable if you have need for that.
I should warn you that it isn't good practice to overuse global variables unnecessarily or overly. See: https://stackoverflow.com/a/19158418/4671205

Does print function have more 'privilege' in python

def func_print_x():
## x += 1 ## if uncomment this line, it will raise UnboundLocalError: local variable 'x' referenced before assignment
print x
if __name__ = '__main__':
x = 4
func_print_x()
In the function func_print_x(), there are two rules:
for the line 'x += 1', the variable x is regard as local variable;
when come to the line 'print x', the variable x seem to be global variable.
Does print function have more 'privilege'?
def f():
global s
print s
s = "That's clear."
print s
s = "Python is great!"
f()
print s
o/p
Python is great!
That's clear.
That's clear.
but whne you do not have global
def f():
print s
s = "Me too."
print s
s = "I hate spam."
f()
print s
o/p
UnboundLocalError: local variable 's' referenced before assignment
You will get the above error if you try to assign some values to s
if you try to print the value of s it will be printed inside the function

Categories

Resources