Declaring global variables - python

I have 2 question regarding global variables:
Why can't I declare a list as a global variable as so: global list_ex = []?
I have already defined a global variable that I am trying to use in a function, but can't:
global column
def fx_foo(cols):
common = set(cols).intersection(set(column)) #Error Here!!
When I try to access column inside the function, I get an error:
NameError: global name 'column' is not defined

You are not using global correctly. You don't need to use it at all.
You need to actually set a global column variable, there is none right now. global does not make the variable available. Just create a global column first:
column = []
then refer to it in your function. That is what the NameError exception is trying to tell you; Python cannot find the global column variable, you didn't assign anything to the name so it doesn't exist.
You only need to use global if you want to assign to a global column in your function:
def somefunction():
global column
column = [1, 2, 3]
Here the global keyword is needed to distinguish column from a local variable in the function.
Compare:
>>> foo = 1
>>> def set_foo():
... foo = 2
...
>>> set_foo()
>>> foo
1
to
>>> foo = 1
>>> def set_foo():
... global foo
... foo = 2
...
>>> set_foo()
>>> foo
2
The first form only set a local variable, the second form set the global variable instead.

The keyword global means you are explicitly using a variable declared outside the scope of a function.
Your variable must be declared normally:
column = []
and declared global in the function that uses it
def fx_foo(cols):
global column
common = set(cols).intersection(set(column))
It is used to allow python to distinguish between new local variables and reused global variables.

this will work :
column =[]
def fx_foo(cols):
global column
common = set(cols).intersection(set(column))
but this will work even without global as column will be considered as nonlocal here
column =[]
def fx_foo(cols):
common = set(cols).intersection(set(column))
I think It is more interesting to assign data to column if You want to display global feature (as You can use column from nonlocals without global declaration if you don't assign anything to it)
column =[]
def fx_foo(cols):
global column
column = set(cols).intersection(set(column))
or
def fx_foo(cols):
column =[]
global column
column = set(cols).intersection(set(column))

Global variables need to be declared global inside of the function not on the outside. A variable declared outside a function is by default global.
Functions don't need to declare a variable as global if they only need to access it. The global declaration is just if you need to modify the global variable.
Therefore, in your case, I suggest that you look into what column actually is when you're passing it to the function, because I think the problem may have something to do with that.

Related

Python : define a constant used by several functions [duplicate]

This question already has answers here:
Why isn't the 'global' keyword needed to access a global variable?
(11 answers)
Closed 2 years ago.
In Python, I was wondering something about defining a variable in a module which can be used by all functions in that module.
I know that if I define a variable outside function, I can access that variable in a function by introducing global
e.g : inside a module name gas.py
R = 8.314 # univsersal gas constant
def pressure(T, V, n):
global R
P = n*R*T/V
return P
def temperature(P,V,n):
global R
T = P*V/(R*n)
return T
But as you can see, I have to write global R inside each function.
Is there a way that I can access R without writing global R inside each function ?
For example :
R = 8.314 # univsersal gas constant
def pressure(T, V, n):
P = n*R*T/V
return P
def temperature(P,V,n):
T = P*V/(R*n)
return T
Thank you
In python, you can read the value of a global variable without declaring it global.
You only need the global declaration when you want to change the value of a global variable. So in your case, you can just delete the all global declarations.
No, in Python a global variables works in a different way compared to other programming languages.
If you want to access a variable contained outside a function, you can just call it like a regular variable, for example:
word = "hello"
def function():
print(word)
function()
Output: hello
If you want to edit a variable locally, but not globally, you have to reassign the variable inside the function, for example:
word = "hello"
def function():
word = "world"
print(word)
print(word)
Output: hello, because we reassigned the variable only inside the function, so the global value of the variable word is still hello
But, if we want to edit a global variable (such as in case 1) in a non-global scope (local scope) and we want to manipulate the value of that variable inside a function, we have to use the global declaration, for example:
word = "hello"
def function():
global word
word = "world"
function()
print(word)
Now the Output will be world.

Use a dictionary to refer to a global variable inside a function (Python)

I'm using a dictionary to refer to a global variable in Python inside a function. I want to use the function to update the global variable. (In reality my global variables are more complicated than this.)
global_variable_A=5
global_variable_B=1
dictionary={'A':global_variable_A,'B':global_variable_B}
def f(x,glob):
global global_variable_A
dictionary[glob]+=x
f(2,'A')
print(global_variable_A)
This returns 5 rather than 7. I understand why, is there anyway to let Python know that I mean the variable dictionary[glob] to refer to the global rather than the local variable, while still referring to the variable through a dictionary?
Thanks for your time, and apologies if I've missed something completely obvious.
When you assign a value to a name name = 5, you're creating a reference to 5 that you can use the identifier name to access. Normally, if you then have some code with a narrower scope, you can either use that reference
def f():
print(name)
or create a local reference using the same identifier, potentially to an unrelated value
def g():
name = 100
print(name)
The global keyword allows you to instead manipulate the identifier as if you weren;t in the more narrow scope, allowing you to reassign the global name to a different reference:
def h():
global name
name = 100
h()
print(name) # 100
However, when you use a reference to create another reference, there isn't any relation ship between those two references. So
name = 5
l = [name]
leaves us with two references to the value 5: one from the identifier name, and one from the first position of l. Crucially, those two references are not related; we can change one without changing the other.
name = 6
print(l) # [5]
One way to accomplish what you want is to use a boxed type. That means that you create an object that points to another object. All of your references can then point to the first object (the box) and you can freely change what it points to (the thing "inside" the box), by only updating a single reference:
class Box:
def __init__(self, value):
self.value = value
box = Box(5)
l = [box]
box.value = 10
print(l[0].value) # 10
If you think you need to do this, there's a design flaw in your code. I really wouldn't recommend doing this.
global_a = 5
def add_to_global(key, value):
globals()[key] += value
add_to_global("global_a", 2)
print(global_a)
Output:
7

Can access a list declared within a function inside another function withing the first function, but not a variable without using global attribute

Class 'Test' contains function 'test_variables'.
Functions 'update_d' and 'update_a' are declared within 'test_variables()'.
Variable 'index' is initialized to 0 in 'test_variables'
List A [1,2] is initialized in 'test_variables'
'update_d' and 'update_a' updates 'index' and prints it.
I can access elements of list A without using the global attribute,
but to access 'index' I have declared'global index' within 'update_d' and 'update_a'.
Why can I not access the variable index without global but can access a list?
index=0
class Test():
def test_variables():
def update_d():
global index
index=index+1+A[0]
print(index)
def update_a():
global index
index=index+1+A[1]
print(index)
index=0
A=[1,2]
update_d()
update_a()
test_variables()
In Python, the global keyword is only needed when you are writing to a variable. Inside test_variable() you have defined a NEW variable named index, though it seems your intent was to write to the variable defined outside that scope.
When you read from a variable name, Python starts in the innermost scope and if the name isn't found, continues looking in the containing scopes.
When you write to a variable name, Python only looks locally and creates a new variable if one of that name isn't found. The global keyword tells Python that the local scope should reference that name globally on assignment.
For this reason, global variables work best as constants, and variables you need to change should probably be passed in to a function as a parameter and the new value returned.
The list A (in addition to update_a and update_b) is defined within Test, while index is not.
It's not correct way of using classes.
Code:
class Test:
A = (1, 2)
def __init__(self, index):
self.index = index
def update_d(self):
self.index += 1 + self.A[0]
print(self.index)
def update_a(self):
self.index += 1 + self.A[1]
print(self.index)
def test_variables(self):
self.update_d()
self.update_a()
idx = 0
tst = Test(idx)
tst.test_variables()
Provided code does same as yours but with correct usage of classes.

How to set a global variable

I tried to set a global variable in a funktion.
global the variable is set to Kategorie = ''
In one of my function I would like to set it to a other value:
elif methode=='show_select_dialog':
writeLog('Methode: show select dialog', level=xbmc.LOGDEBUG)
dialog = xbmcgui.Dialog()
cats = [__LS__(30120), __LS__(30121), __LS__(30122), __LS__(30123), __LS__(30116)]
ret = dialog.select(__LS__(30011), cats)
if ret == 6:
refreshWidget()
elif 0 <= ret <= 5:
writeLog('%s selected' % (cats[ret]), level=xbmc.LOGDEBUG)
global Kategorie
Kategorie = (cats[ret])
refreshWidget()
If I log the variable Kategorie in function refreshWidget the value is correct (cats[ret]), but after that if the function refreshedWidget is called again the value is gone...
elif methode == 'get_item_serienplaner':
sp_items = refreshWidget()
Once I have changed the variable to cats[ret] I would need it as cats[ret]
You have to declare your var outside your functions and everytime you want to use it inside a function you need to specify the global varName. As i see your global var name at declaration is Kategory and after you use Kategorie.
Python wants to make sure that you really know that you are using global variables by explicitly requiring the global keyword.
To use a global variable within a function you have to explicitly delcare you are using it.
Here a small example:
myGlobalVar= 0
def set_globvar():
global myGlobalVar # Needed to modify global copy of globvar
myGlobalVar = 5
def print_globvar():
print myGlobalVar # No need for global declaration to read value of myGlobalVar
set_globvar()
print_globvar() # Prints 5
in your case I see that you declare that you want to access global Kategorie but you do not declare access to global Kategory. I do not know if this is a simple typo or if they are 2 different variable. In any case you need to write global yourGlobalVariable
Are there really any globals in python? Yes there is a global keyword that allows you to access varibles in file scope. Another way of accessing the variable is to use the import statement. Lets say you have a file named file.py. In order to write to the variable you could. You could access another files variables just as easy.
import file
anyVariable = 42
# ...
def aFunc():
file.anyVarible = file.anyVarible + 1

Python and closed variables [duplicate]

This question already has answers here:
nonlocal keyword in Python 2.x
(10 answers)
Closed 6 months ago.
Have a look at this code:
def closure():
value = False
def method_1():
value = True
def method_2():
print 'value is:', value
method_1()
method_2()
closure()
I would expect it to print 'Value is: True' but it doesn't. Why is this and what is the solution?
This happens because method_1 gets its own local scope where it can declare variables. Python sees value = True and thinks you're creating a new variable named value, local to method_1.
The reason Python does this is to avoid polluting the outer scope's locals with variables from an inner function. (You wouldn't want assignments in regular, module-level functions to result in global variables being created!)
If you don't assign to value, then Python searches the outer scopes looking for the variable (so reading the variable works as expected, as demonstrated by your method_2).
One way to get around this is by using a mutable object instead of assigment:
result = { 'value': False }
def method_1():
result['value'] = True
In Python 3, the nonlocal statement (see also docs) was added for exactly this scenario:
def method_1():
nonlocal value
value = True # Works as expected -- assigns to `value` from outer scope
In method_1, Python assumes (quite sensibly!) that value is a local variable. Whenever you assign to a variable name inside a function, it is assumed that that variable name is a new local variable. If you want it to be global, then you have to declare it as global, and if you want it to be "nonlocal", in Python 3, you can declare it nonlocal, but in Python 2, you have to do something uglier: store the value in a container. That avoids having to reassign the variable name, and so avoids the scoping ambiguity.
def method_1_global():
global value
value = True
def method_1_nonlocal_P3():
nonlocal value
value = True
value = [False]
def method_1_nonlocal_P2():
value[0] = True
When you assign to a variable, it assumes the variable is of local scope. So the value in method_1 is not the value in closure.
If you want this to work on Python 3, add a line to method_1: nonlocal value.
On Python 2,
def closure():
value = [False]
def method_1():
value[0] = True
def method_2():
print 'value is:', value
method_1()
method_2()
closure()
is one possible work-around.
This is because you are not actually modified the closed-over variable - you are masking it with a new one that has the same name. In python 2.x there is no easy way around this, which is why the nonlocal keyword was added in python 3.
This can be worked around, however, using mutable types like list and dictionary. There is a good example in this answer.
To avoid this, you can use a list.
value = [False]
def method_1():
value[0] = True
What Python does now is searching in higher levels of the scope as value is not available in the local variables. As value is a list and Python refernces it as a global variable relative to *method_1*, you can treat value as it is, a list.

Categories

Resources