python 3 local variable defined in enclosing scope referenced before assignment - python

I have declared global variables that i need to access and modify in a function in a class. This function loops indefinitely once called and stream data passes through it. I need to be able to use x y z variables inside the function, and redefine their values as stream_data comes through.
My current code looks like this:
x = 10
y = 8
z = 2
class Program():
def function(stream_data):
while True:
try:
a = stream_data['data']
if (a - z) > y:
y = a - z
else:
pass
except:
continue
I get error "local variable y defined in enclosing scope on line 7 referenced before assignment".
How can I format this code so that when the function is first called, it uses the global variables, and then on each subsequent calling it uses the variable y it redefined? Thanks I am new to coding and really need help!

Use
global x, y, z to use the global variables
Like This-
x = 10
y = 8
z = 2
class Program():
def function(stream_data):
while True:
try:
global x,y,z
a = stream_data['data']
if (a - z) > y:
y = a - z
else:
pass
except:
continue
Alternatively, you can also initialize x,y,z within your function.
Let me know if this helps!

Related

Any type of scope resolution operator in Python?

Is there any way to make the python interpreter choose the global variable specifically when there is also a local variable with the same name? (Like C++ has :: operator)
x=50
def fun():
x=20
print("The value of local x is",x)
global x
#How can I display the value of global x here?
print("The value of global x is",x)
print("The value of global x is",x)
fun()
The second print statement inside the function block should display the value of global x.
File "/home/karthik/PycharmProjects/helloworld/scope.py", line 7
global x
^
SyntaxError: name 'x' is used prior to global declaration
Process finished with exit code 1
Python does not have a direct equivalent to the :: operator (typically that kind of thing is handled by the dot .). To access a variable from an outer scope, assign it to a different name as to not shadow it:
x = 50
def fun():
x = 20
print(x) # 20
print(x_) # 50
print(x) # 50
x_ = x
fun()
But of course Python would not be Python if there weren't a hack around this... What you describe is actually possible, but I do not recommend it:
x = 50
def fun():
x = 20
print(x) # 20
print(globals()['x']) # 50
print(x) # 50
fun()
I don't know any way to do this (and I am not an expert). The two solutions that I can think of are to give another name to your local x (like xLoc), or to put your global x in argument, like this :
x=50
def fun(xGlob):
x=20
print("The value of local x is",x)
print("The value of global x is",xGlob)
print("The value of global x is",x)
fun(x)
Is this answering your question ?

Returning functions

I have functions that use returned variables.
How do I call them in a main function like this:
text = 'a'
def a(text):
text = x
return x
def b(x):
x = z
return z
def main():
# What do I put here to call function a and b?
main()
How do I call them
You already know how to call them ;)
def main():
...
main()
So I assume you are bewildered by:
def a(text):
text = x
return x
That x is not defined in a nor is it passed by argument to it. But that's OK. In python, all variables defined outside function are still visible inside it. Only exception is if argument of function have the same name as one of those variables. Then argument will take precedence.
This mechanism is called closure. Function close over some variable that already exists in scope when function is defined.
You can learn about it some more here:
https://www.learnpython.org/en/Closures
text = 'a'
def a(text):
text = x
return x
def b(x):
x = z
return z
def main():
x = a(text)
z = b(x)
main()
This might be what you want
It is not clear what are you trying to achieve. You are using variable x in the function a and variable z in function b without defining these two variables.
Moreover, you are setting variable text in function a without capturing it using statement global, look here for more information.
And global variables are considered to be bad practice.

Difference between local variable and global variable

I'm confused on the difference between local variables and global variables. I know that global variables are declared outside a function while local is declared in a function. However, I'm wondering if it is as so:
def func(l):
a = 0
n = len(l)
w = l[0]
while...
My question is, in the function i wrote as an example, i know that a is a local variable but what about the other two? are they local variables too?
l is a location variable that you passed into the function, and so is w since w is a "copy" of l[0]
To have a global variable you need to declare the variable as global using the global keyword.
x = 1
y = 2
def func(l):
global x
x = 4
l = 5
print("x is {0}, y is {1}".format(x,l))
func(y)
print("x is {0}, y is {1}".format(x,y))
Returns:
x is 4, y is 5
x is 4, y is 2
Notice how x is now changed but y isn't?
Note that lists are special because you don't need to declare the global keyword to append or remove from them:
x = []
def func():
x.append(3)
print("x is {0}".format(x))
func()
print("x is {0}".format(x))
Returns:
x is [3]
x is [3]
But references to lists are not global because they are a 'copy' of it :
x = [3]
y = 1
def func():
y = x[0]
print("y is {0}".format(y))
func()
print("y is {0}".format(y))
Returns:
y is 3
y is 1
Also Reassigning the variable that was a list is not global:
x = [3]
def func():
x = [2]
print("x is {0}".format(x))
func()
print("x is {0}".format(x))
Returns:
x is [2]
x is [3]
Also note that there are always a better way to do something than to declare global variables, because as your code scales it will get messier.
All those variables are assigned values and that automatically declares them in the local scope. So they are local variables.
Even if they had been declared outside in the global scope, they would still be local.
Unless you used the global keyword which tells the interpreter that the current scope refers to a previously declared global or creates a new one in the global context if none with the same name exists.
def func(l):
global n # n is declared in the global scope
a = 0
n = len(l)
w = l[0]
while...
func()
print(n)
All the variables in your function are local, usable by that function only. Global variables are usable by all functions in the class. In your function
def func(l):
a = 0
n = len(l)
w = l[0]
while...
>>>a
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'a' is not defined
a, n, w, and l are not usable outside of the func scope. If you did something like this...
a = 0
def func(l):
n = len(l)
w = l[0]
while...
>>>a
0
I just happened to come across this read which provides you with a lot of detail on variable declaration and scope.
[Python Doc the rule for local and global variables]:
In Python, variables that are only referenced inside a function are
implicitly global. If a variable is assigned a value anywhere within
the function’s body, it’s assumed to be a local unless explicitly
declared as global. illustrate this with your example:
Use your example to illustrate, all variables declared inside the func are local variables. and even values declared outside of the function. like variable x it has no parent function but it is still actually NOT a global variable. x just get commits to memory before the func gets called
x = 5 #actually local
def func(l):
a = 0
n = len(l)
w = l[0]
print(x) # x is local we call call it, use it to iterate but thats is pretty much it
if we try to modify the local variable x you would get an error:
x = 5
def func(l):
a = 0
n = len(l)
w = l[0]
x = x + 1 # can't do this because we are referning a variable before the funtion scope. and `x` is not global
UnboundLocalError: local variable 'x' referenced before assignment
but now if we define x as global then we can freely modify it as Python know anywhere when we call x is references to the same variable and thus the same memory address
x = 5
def func():
global x
x = x + 1
func()
print(x)
it prints out : 6 for the value of x
Hope through this example you see that global variable can be accessed anywhere in the program. Whereas local variable can only be accessed within its function scope. Also, remember that even though global variables can be accessed locally, it cannot be modified locally inherently.
Local Variable : When we declare a variable inside a function, it becomes a local variable.
global variable : When we declare a variable outside a function , it becomes a global variable.
A python program understand difference local vs global variable
#same name for local and global variable.
a = 1 #this is global variable
def my_function():
a = 2 #this is local variable
print("a= ", a) #display local var
my_function()
print("a = ", a) #display global var.
This program to access global variable
a = 1 #This is global var
def my_function():
global a #This is global var.
print("global a= ", a) #display new value
a = 2 #modify global var value
print("modify a = ", a) #display a new value
my_function()
print("global a= ", a) #display modified value

Saving an assignment made within a function

If I have this code:
x = 9
def changex():
x = 10
return x
changex()
print x
when I print x it doesn't say that it is 10, how do I make it so that it is 10 without doing print changex()? Thank you
In Python, if you want code from inside a function to affect global variables, you need to add a global statement:
x = 9
def changex():
global x
x = 10
return x
changex()
print x
You can't change the x object, but you can redefine it:
x = changex()
print x
You could also put global x at the beginning of the function so that it will be redefining the global variable instead of defining a local one.

Python global variable/scope confusion [duplicate]

This question already has answers here:
UnboundLocalError trying to use a variable (supposed to be global) that is (re)assigned (even after first use)
(14 answers)
Using global variables in a function
(25 answers)
Closed 7 years ago.
I've started teaching myself python, and have noticed something strange to do with global variables and scope.
When I run this:
x = 2
y = 3
z=17
def add_nums():
y = 6
return z+y
The result of 23 is printed...
However, when I expand the return to be:
x = 2
y = 3
z=17
def add_nums():
y = 6
z = z + y
return z
I get the following error on line 6:
Local name referenced but not bound to a value.
A local name was used before it was created. You need to define the
method or variable before you try to use it.
I'm confused as why I am getting an error here, as z is global an accessible.
When a variable is on the left side of an equal sign python will create a local variable. When the variable is on the right side of the equal sign python will try to look for a local variable and if he can't find one then it will use a global variable. In your example, z is on the right and left side of the equal sign, to avoid ambiguities python raises an error. You need to use the global syntax to avoid this:
x = 2
y = 3
z = 17
def add_nums():
global z
y = 6
z = z + y
return z
Python determines scope by binding operations. Assignment is a binding operation, as is importing, using a name as a target in except .. as, with .. as or a for loop, or by creating a function or a class.
When a name is bound in a scope, it is local to that scope. If a name is used but not bound, it is non-local; the compiler will determine at compile time what the scope should be then. In your case there is no parent scope other than the global scope, so any name not bound to is considered a global.
Since your second example binds to z (you used z =, an assignment), the name is local to the function.
If a name is bound to in a scope but you want to tell Python that it should be global anyway, you need to do so explicitly:
x = 2
y = 3
z=17
def add_nums():
global z
y = 6
z = z + y
return z
The global z line tells the compiler that z should be a global, even though you bind to it.
Let's analyse the marked line.
x = 2
y = 3
z = 17
def add_nums():
y = 6
z = z + y <--- THIS LINE
return z
z ... a new local variable is created
= ... we are going to assign a value to it
z ... this variable exists (the new local one) but it has no value yet.
+ y ... this part is not reached.
The result is an error message "UnboundLocalError: local variable 'z' referenced before assignment".
If you want the names y and z inside the function body to reference your global variables when you assign something to them, you must declare them like this:
x = 2
y = 3
z=17
def add_nums():
global y
global z
y = 6
z = z + y
return z
Otherwise, when you perform an assignment to the variables y and z inside the function, you create different names that exist only in the local scope of the function.
As pointed out in the comments, you can reference a global variable and even modify it if it is mutable (i.e. append something to a list) without explicitly declaring it global as long as you don't try to assign to it.

Categories

Resources