Globals from one file are undefined in another - python

This is partially linked with my last question. I imported an object called current_user. I pass it in 2 variables from file 1 called guy.py, the variables are log_name and log_pass. These 2 variables are inputs from 2 entries and they're global. I made a function to import these global variables along with every other global that I have in gui.py. I'm still confused as to why the global variables are still being undefined.
This is the function which I use to import the object current_user:
def objects():
global log_name,log_pass
current_user = User(log_name,log_pass,score=0)
return current_user
And this is the function I tried using to import my global variables:
def global_vars():
global main_window,reg_window,name_entry,pass_entry,log_name_entry,log_pass_entry,log_name,log_pass,c,conn,query,data
The error I get is this:
current_user = User(log_name,log_pass,score=0)
NameError: name 'log_name' is not defined

as I understand you have to .py files: one is called guy.py the other I will call test.py:
so if you want to import values from guy.py to test.py. First define variables in guy.py like so:
log_name = yourvalue
log_pass = yourvalue
then go to test.py (it has to be in the same directory (to make it simple)) and import:
from guy import log_name, log_pass
now you can use these values in test.py and whenever you change the value in guy.py it will be changed in test.py. Also there is no need to make values global (for this case I think)

Related

How to carry variables from imported functions to the main file (Python 3.8.3

I'm making a small game and wanted a settings page function that's in a seperate .py file to keep things more clean and easily editable. I have a global variable called textSpeed (which I use the global keyword to use properly in the function) which I change in this runSettings function, but when I print the variable back in my main file it hasn't changed.
The code in the main file (main.py)
from settings import runSettings
textSpeed = "not set"
runSettings()
print(textSpeed)
The code from the settings fuction file (settings.py)
def runSettings():
global textSpeed
textSpeed = input("select text speed. ")
print(textSpeed)
return textSpeed
textSpeed is a local variable - local to the main module.
You need to reference the variable from settings.
import settings
settings.textSpeed = "not set"
runSettings()
print(settings.textSpeed)
To avoid circular import, I advise you to create a third file if you wish to keep it this way. Let's call it varSpeed.py with the following code:
global textSpeed
textSpeed = "not set"
Then you can import varSpeed from both other files have access to that variable without the circular issue.
The runSettings function already retuns the value it sets as well. Instead of messing with mixing namespaces and importing global variables, just use the returned value in main.py:
textSpeed = runSettings()
the problem is that you are trying to change a variable from a different file, while you have not imported the file. I think the easiest way to handle this is to use a class variable like this:
Main file:
from class_file import MyClass
MyClass.run_settings()
print(MyClass.text_speed)
Settings file:
class MyClass:
text_speed = 'n/a'
#staticmethod
def run_settings():
MyClass.text_speed = input("Select text speed: ")
return MyClass.text_speed

Python 3: Importing file containing variables to be used as constants

I want to use a config.py file in which I will be declaring some constants to be used in mainFile.py.
I'll be defining these "constant variables" using Capital letters.
I want to make it easier to configure the mainFile.py parameters by defining the constants only in config.py.
Ofcourse, in mainFile.py, the values of these constant are by no means altered.
So, my question is :
If in mainFile.py I use "From config.py import *", are the "constant variables" defined in config.py used as global variables in mainFile.py?
E.g. inn functions defined within mainFile.py, do I need to re-define these variables as global in order to use them?
You can simply write import config, and all of your constants will be accessible to your code in mainFile.py.
There are two options:
As already pointed out by #Josh, in config.py you name your variables, such as m=10, t=52, and so on. Then on mainFile.py you import config and access your variables as config.m that will result in 10. Like:
y = config.m
y = 10
The second option is a bit longer. You create a function such as
def m():
m = 10
return m
Then on mainFile.py you import config and access the variable as config.m() that will yield 10. Like
z = config.m()
z = 10
global is required if you are modifying the imported variable in some case and you need to reflect that value on all other places where the variable is being accessed.
since you are just reading the value of the imported variable here, global is no required. also inside functions if any variable is read first it searches on local scope then on global scope. So no global required inside function for reading purpose.

Exec can't access variables in it's parent environment

My friend asked me to build a function that can execute code in a for loop so, I was doing that and I was using exec in the same file I was declaring a variable name, now when I access name from exec, it says NameError: name 'name' is not defined
This thing is in multiple files, one that runs everything, second that includes all functions and one that calls all functions
I have tried to define variables inside exec and sure, it works.
I have tried Accessing variables in functions.py(File that contains every function) file and it works too.
I have tried merging functions.py and test.py(the file that's using exec) and then running it directly through python and it worked
My functions.py file
def forloop(current, maximum, code):
for x in range(current, maximum):
exec(str(code), globals())
My 'test.py'(It's the one where I call functions)
from functions import *
name = 'Ameer'
forloop(1,3,"""
echo(name)
""")
And, I am running it all through another exec in my 'runner.py'
from functions import *
file = open('test.py', "r+")
content = file.read()
exec(content)
Now, it's giving me an error saying NameError: name 'name' is not defined when it is defined. Please can you guys help me with this issue
You need to use the variables from the place where forloop is called.
import inspect
def forloop(current, maximum, code):
frame = inspect.currentframe().f_back
for x in range(current, maximum):
exec(str(code), frame.f_globals, frame.f_locals)

Python global dict across different file script

Hello. I am trying to use a global dict created in main.py, which is called in functions.py.
In my main.py I have:
import sys,os,...
import functions.py #import my second file
matrix = {}
matrix_do_something
search_the_matrix(value) #which is defined in functions.py
#FILE: functions.py
def search_the_matrix(value):
global matrix
if value in matrix:
return True
else:
return False
and I get this error:
NameError: global name 'matrix' is not defined
I have read a solution on stackoverflow, which says to put everything in a global file and then call from every file global.matrix[value] but I don't want this. I want just call it matrix and think of it as my global matrix. Is this possible?
Thank you in advance
In functions.py you would have to import it
from main import matrix
Though I would want to come up with a better name for my module than main.
If you want an object to be available in a module / file you need to either create it there or import it from somewhere else.

Global variable with imports

first.py
myGlobal = "hello"
def changeGlobal():
myGlobal="bye"
second.py
from first import *
changeGlobal()
print myGlobal
The output I get is
hello
although I thought it should be
bye
Why doesn't the global variable myGlobal changes after the call to the changeGlobal() function?
Try:
def changeGlobal():
global myGlobal
myGlobal = "bye"
Actually, that doesn't work either. When you import *, you create a new local module global myGlobal that is immune to the change you intend (as long as you're not mutating the variable, see below). You can use this instead:
import nice
nice.changeGlobal()
print nice.myGlobal
Or:
myGlobal = "hello"
def changeGlobal():
global myGlobal
myGlobal="bye"
changeGlobal()
However, if your global is a mutable container, you're now holding a reference to a mutable and are able to see changes done to it:
myGlobal = ["hello"]
def changeGlobal():
myGlobal[0] = "bye"
I had once the same concern as yours and reading the following section from Norman Matloff's Quick and Painless Python Tutorial was really a good help. Here is what you need to understand (copied from Matloff's book):
Python does not truly allow global variables in the sense that C/C++ do. An imported Python module will not have direct access to the globals in the module which imports it, nor vice versa.
For instance, consider these two files, x.py,
# x.py
import y
def f():
global x
x = 6
def main():
global x
x = 3
f()
y.g()
if __name__ == ’__main__’:
main()
and y.py:
# y.py
def g():
global x
x += 1
The variable x in x.py is visible throughout the module x.py, but not in y.py. In fact, execution of the line
x += 1
in the latter will cause an error message to appear, “global name ’x’ is not defined.”
Indeed, a global variable in a module is merely an attribute (i.e. a member entity) of that module, similar to a class variable’s role within a class. When module B is imported by module A, B’s namespace is copied to A’s. If module B has a global variable X, then module A will create a variable of that name, whose initial value is whatever module B had for its variable of that name at the time of importing. But changes to X in one of the modules will NOT be reflected in the other.
Say X does change in B, but we want code in A to be able to get the latest value of X in B. We can do that by including a function, say named GetX() in B. Assuming that A imported everything from B, then A will get a function GetX() which is a copy of B’s function of that name, and whose sole purpose is to return the value of X. Unless B changes that function (which is possible, e.g. functions may be assigned), the functions in the two modules will always be the same, and thus A can use its function to get the value of X in B.
Python global variables are not global
As wassimans points out above they are essentially attributes within the scope of the module they are defined in (or the module that contains the function that defined them).
The first confusion(bug) people run into is not realizing that functions have a local name space and that setting a variable in a function makes it a local to the function even when they intended for it to change a (global) variable of the same name in the enclosing module. (declaring the name
in a 'global' statement in the function, or accessing the (global) variable before setting it.)
The second confusion(bug) people run into is that each module (ie imported file) contains its own so called 'global' name space. I guess python things the world(globe) is the module -- perhaps we are looking for 'universal' variables that span more than one globe.
The third confusion (that I'm starting to understand now) is where are the 'globals' in the __main__ module? Ie if you start python from the command line in interactive mode, or if you invoke python script (type the name of the foo.py from the command shell) -- there is no import of a module whose name you can use.
The contents of 'globals()' or globals().keys() -- which gives you a list of the globals -- seems to be accessible as: dir(sys.modules['__main__'])
It seems that the module for the loaded python script (or the interactive session with no loaded script), the one named in: __name__, has no global name, but is accessible as the module whose name is '__main__' in the system's list of all active modules, sys.modules

Categories

Resources