Python modify global variable [duplicate] - python

This question already has answers here:
Python global variables don't seem to work across modules
(3 answers)
Closed 3 years ago.
So, this is a bit tricky.
file1.py
a = None
def set_a():
global a
a = 10
file2.py
from file1 import a, set_a
set_a()
print(a)
output:
None
Why a's value didn't change? I know there are other ways to change the value of a, but why this doesn't work?

The big problem is where globals actually lives. Each script has its own globals. So the globals that is in set_a really points to file1's scope:
import file1
file1.set_a()
a
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'a' is not defined
file1.a
10
This change does not persist to your calling script. So let's just avoid the global entirely.
It would be much clearer for the function to just return the value, which you can name whatever you want in the calling script:
# file1.py
def set_a():
return 10
# file2.py
from file1 import set_a
# this doesn't have any reliance on a name existing
# in any namespaces
a = set_a()
The general concensus on the issue is to avoid globals where possible, as they can make your code difficult to maintain.

Related

Why doesn't this simple Python script run?

I am writing a large program where I need to pass data/variables between functions. Note: I'm a hobbyist and OOP is out of my grasp, so just looking for a non-OOP answer!
I'm using functions to try and make the script modular and avoid having one long messy script. But the program uses a dataframe and lots of different variables which many of the functions will need to access. I don't want to specify every single variable in every function call so would like to be able to access global variables from individual functions. I can do this when the def function(): is in the same script, but I am running into a problem when I try and call global variables when importing a function from a script. Simple reprex:
from test_func import p_func
a = "yes!"
p_func()
calling p_func() from test_func.py
def p_func():
global a
print(a)
generates the error:
Traceback (most recent call last):
File "test.py", line 5, in <module>
p_func()
File "test_func.py", line 5, in p_func
print(a)
NameError: name 'a' is not defined
What am I missing?
You need to change your import line to be:
from test_func import p_func, a
Variables are imported from other modules the same way that functions are.
That said. This is really, really a bad idea as others above has said. Your best off putting all your variables into a single data structure of some sort

Different results for different import ways on accessing cross-module variable [duplicate]

This question already has answers here:
Accessing a Python global variable across files
(2 answers)
Closed 8 years ago.
I have two modules: a.py and b.py
a.py:
foo = 0
def increase():
global foo
foo += 1
b.py:
from a import *
increase()
print(foo)
Run the b.py will get the result: 0, but my expect result is 1
Then I modified the b.py
b.py:
import a
a.increase()
print(a.foo)
Then I get the correct result: 1
My question is why the first edition of b.py getting a wrong result. What's the correct way to import a global variable?
The correct way to import a global variable is to redesign your code so that you don't need to. You should import functions, and perhaps constants (conventionally UPPER_CASE in Python), but never global variables. Global variables are bad enough in libraries, but using them across multiple modules is just asking for trouble.

Exec statement won't properly define names [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
declaring a global dynamic variable in python
>>> def f():
global cat
exec 'cat'+'="meow"'
return
>>> f()
>>> cat
Traceback (most recent call last):
File "<pyshell#23>", line 1, in <module>
cat
NameError: name 'cat' is not defined
This is just a stripped down example of the issue I've come across. In my actual script, I need various instances of a class be created and named, hence the exec statement.
Just calling
exec 'cat'+'="meow"'
directly in the shell works fine, but as soon as it's packed in a function, it doesn't seem to work anymore.
I still don't understand why you are using exec, its a bad design choice and alternatives are usually easier, for example instead of global and then something else you could simply do this
ns = {}
def f():
ns["cat"] = "miow"
print ns
Now isn't that cleaner?
looks like the exec ignores the global, the documentation is a bit vague. but this works:
>>> def f():
... global cat
... exec 'global cat; cat'+'="meow"'
...
>>>
>>> f()
>>> cat
'meow'

Is it possible to import to the global scope from inside a function (Python)?

I am trying to import a module from inside a function and have it be available to my whole file the same way it would be if I imported outside any functions and before all the other code. The reason it is in a function is because I don't have much control over the structure of the script. Is this possible without resorting to things like hacking __builtin__ or passing what I need all around my code?
How about something like globals()["os"] = __import__("os")?
I guess this could be wrapped in a generic function if you wanted since the module name is a string.
Seeing your new comments, I want to emphasize that this sounds unnecessary. You're actually modifying the script more by importing within a function than by importing at the top of the script in the normal way. Still, in the spirit of answering the question asked, I'm leaving my previous answer.
I'm honestly not certain this is the correct way to do this, but a quick check confirms that if you declare the module name as global within the function before importing, it is imported into the global namespace.
>>> def import_re():
... global re
... import re
...
>>> re
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 're' is not defined
>>> import_re()
>>> re
<module 're' from '/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/re.pyc'>
Don't do this unless you really have to -- and then write it in big red letters, so to speak.

Python: Help with UnboundLocalError: local variable referenced before assignment

I keep getting this error for a portion of my code.
Traceback (most recent call last):
File "./mang.py", line 1688, in <module>
files, tsize = logger()
File "./mang.py", line 1466, in logger
nl = sshfile(list, "nl")
UnboundLocalError: local variable 'sshfile' referenced before assignment
I haven't put the code up cause it goes back and forth between functions. I'm wondering if anyone could tell me why python is spitting this error? sshfile is not a variable it's a class.
You probably haven't imported the file which contains the definition of sshfile, or you need to qualify the class name with the package name. It depends on how you imported it.
What package does it come from? Where is it defined?
Update
For anyone else reading this, after a discussion in the comments it turned out that the problem was that the name sshfile had been used further down in the function as a variable name, like this:
class sshfile:
pass
def a():
f = sshfile() # UnboundLocalError here
sshfile = 0
a()
The solution is to not use a variable name that hides a class name that you need to use.

Categories