Global Variable from a different file Python
Asked Answered
B

8

63

So I have two different files somewhat like this:

file1.py

from file2 import *
foo = "bar"
test = SomeClass()

file2.py

class SomeClass :
    def __init__ (self):
        global foo
        print foo

However I cannot seem to get file2 to recognize variables from file1 even though its imported into file1 already. It would be extremely helpful if this is possible in some way.

Butterfat answered 3/8, 2010 at 20:28 Comment(2)
By the way, as a general principle, it's not really recommended to do from module import * because it makes it hard to see where any given imported variable comes from. Also, don't end your statements with semicolons in Python.Holograph
It also makes impossible for a linter to detect if you are using an undefined identifierAmarillis
N
109

Importing file2 in file1.py makes the global (i.e., module level) names bound in file2 available to following code in file1 -- the only such name is SomeClass. It does not do the reverse: names defined in file1 are not made available to code in file2 when file1 imports file2. This would be the case even if you imported the right way (import file2, as @nate correctly recommends) rather than in the horrible, horrible way you're doing it (if everybody under the Sun forgot the very existence of the construct from ... import *, life would be so much better for everybody).

Apparently you want to make global names defined in file1 available to code in file2 and vice versa. This is known as a "cyclical dependency" and is a terrible idea (in Python, or anywhere else for that matter).

So, rather than showing you the incredibly fragile, often unmaintainable hacks to achieve (some semblance of) a cyclical dependency in Python, I'd much rather discuss the many excellent way in which you can avoid such terrible structure.

For example, you could put global names that need to be available to both modules in a third module (e.g. file3.py, to continue your naming streak;-) and import that third module into each of the other two (import file3 in both file1 and file2, and then use file3.foo etc, that is, qualified names, for the purpose of accessing or setting those global names from either or both of the other modules, not barenames).

Of course, more and more specific help could be offered if you clarified (by editing your Q) exactly why you think you need a cyclical dependency (just one easy prediction: no matter what makes you think you need a cyclical dependency, you're wrong;-).

Necessitate answered 3/8, 2010 at 20:46 Comment(3)
Can file1.py edit the global variables in file3.py, and file2.py automatically reload the new global variables?Outcurve
@LWZ, from experimentation, it looks like immutable types are not updated by default when in shared memory, but mutable types are fine. So you can't share bools directly, but you can share bools inside of dictionaries or lists.Holmium
Cyclical dependencies are very common and often justified (for example in mutual recursion). Even if they were always bad, such a remark would not not belong in the answer, particularly not in the way it's written.Renfred
H
36

When you write

from file2 import *

it actually copies the names defined in file2 into the namespace of file1. So if you reassign those names in file1, by writing

foo = "bar"

for example, it will only make that change in file1, not file2. Note that if you were to change an attribute of foo, say by doing

foo.blah = "bar"

then that change would be reflected in file2, because you are modifying the existing object referred to by the name foo, not replacing it with a new object.

You can get the effect you want by doing this in file1.py:

import file2
file2.foo = "bar"
test = SomeClass()

(note that you should delete from foo import *) although I would suggest thinking carefully about whether you really need to do this. It's not very common that changing one module's variables from within another module is really justified.

Holograph answered 3/8, 2010 at 20:38 Comment(0)
B
22

from file2 import * is making copies. You want to do this:

import file2
print file2.foo
print file2.SomeClass()
Biddick answered 3/8, 2010 at 20:38 Comment(0)
R
11

global is a bit of a misnomer in Python, module_namespace would be more descriptive.

The fully qualified name of foo is file1.foo and the global statement is best shunned as there are usually better ways to accomplish what you want to do. (I can't tell what you want to do from your toy example.)

Reneareneau answered 3/8, 2010 at 20:38 Comment(0)
A
5

After searching, I got this clue: https://instructobit.com/tutorial/108/How-to-share-global-variables-between-files-in-Python

the key is: turn on the function to call the variabel that set to global if a function activated.

then import the variabel again from that file.

i give you the hard example so you can understood:

file chromy.py

from selenium import webdriver
from selenium.webdriver.chrome.options import Options

def opennormal():
    global driver
    options = Options()
    driver = webdriver.Chrome(chrome_options=options)

def gotourl(str):
    url = str
    driver.get(url)

file tester.py

from chromy import * #this command call all function in chromy.py, but the 'driver' variable in opennormal function is not exists yet. run: dir() to check what you call.

opennormal() #this command activate the driver variable to global, but remember, at the first import you not import it

#then do this, this is the key to solve:
from chromy import driver #run dir() to check what you call and compare with the first dir() result.

#because you already re-import the global that you need, you can use it now

url = 'https://www.google.com'
gotourl(url)

That's the way you call the global variable that you set in a function. cheers don't forget to give credit

Archimage answered 23/3, 2019 at 18:55 Comment(0)
C
5

while I do the test following the idea of @robertspierre to put all global variables in a glv.py file and then import it in other files where it is used, the demo codes is given bellow, hope it helps:

  1. the global variable file, glv.py:
# glv.py
glvB = True
glvA = 100
glvS = "tiger"
glvList = [1, 2, 3]
glvTuple = (1, "a")
glvDict = {"Name": "tiger", "age": 100}
  1. sub1.py, it's a file that will import the glv.py file. Two functions are defined to show and change the global variable data in glv.py, showData() and changeData(),
# sub1.py
import glv


def showData():
    print(f"*****glv in sub1*****\n"
          f"glvB={glv.glvB}\n"
          f"glvA={glv.glvA}\n"
          f"glvS={glv.glvS}\n"
          f"glvList={glv.glvList}\n"
          f"glvTuple={glv.glvTuple}\n"
          f"glvDict={glv.glvDict}\n")


def changeData():
    glv.glvB = False
    glv.glvA = 200
    glv.glvS = "bactone"
    glv.glvList = [4, 5, 6]
    glv.glvTuple = (2, "b")
    glv.glvDict = {"Name": "bactone", "age": 0}
  1. sub2.py is another file:
# sub2.py

import glv


def showData():
    print(f"*****glv in sub2*****\n"
          f"glvB={glv.glvB}\n"
          f"glvA={glv.glvA}\n"
          f"glvS={glv.glvS}\n"
          f"glvList={glv.glvList}\n"
          f"glvTuple={glv.glvTuple}\n"
          f"glvDict={glv.glvDict}\n")


def changeData():
    glv.glvB = True
    glv.glvA = 300
    glv.glvS = "bactone"
    glv.glvList = [7, 8, 9]
    glv.glvTuple = (3, "c")
    glv.glvDict = {"Name": "bactone1", "age": 10}
  1. finally we test the global variable in main.py:
import glv
import sub1
import sub2


def showData():
    print(f"*****initial global variable values*****\n"
          f"glvB={glv.glvB}\n"
          f"glvA={glv.glvA}\n"
          f"glvS={glv.glvS}\n"
          f"glvList={glv.glvList}\n"
          f"glvTuple={glv.glvTuple}\n"
          f"glvDict={glv.glvDict}\n")


if __name__ == "__main__":

    showData()  # show initial global variable
    sub1.showData()  # show global variable in sub1
    sub1.changeData()  # change global variable in sub1
    sub2.showData()  # show global variable in sub2
    sub2.changeData()  # change global variable in sub2
    sub1.showData()  # show global variable in sub1 again

the results turns out to be:

*****initial global variable values*****
glvB=True
glvA=100
glvS=tiger
glvList=[1, 2, 3]
glvTuple=(1, 'a')
glvDict={'Name': 'tiger', 'age': 100}

*****glv in sub1*****
glvB=True
glvA=100
glvS=tiger
glvList=[1, 2, 3]
glvTuple=(1, 'a')
glvDict={'Name': 'tiger', 'age': 100}

*****glv in sub2*****
glvB=False
glvA=200
glvS=bactone
glvList=[4, 5, 6]
glvTuple=(2, 'b')
glvDict={'Name': 'bactone', 'age': 0}

*****glv in sub1*****
glvB=True
glvA=300
glvS=bactone
glvList=[7, 8, 9]
glvTuple=(3, 'c')
glvDict={'Name': 'bactone1', 'age': 10}

we can see all kinds of data type works and the change of global variable is automatically reloaded.

Calculation answered 30/5, 2021 at 2:55 Comment(1)
this is exactly what I'm looking for. thanks!Bookish
K
2

I came to the conclusion that you can import globals, but you can not change them once imported. The only exception is if you pass them as arguments. I would love to be wrong on this, so let me know if there is a way to effectively re import updated globals. The two codes below will run.

from b import *  # import all from b.py

global alpha  # declare globals
global bravo
global charlie

alpha = 10  # assign values to globals
bravo = 20
charlie = 15


def run_one():
    one(alpha)  # pass the global to b.py


def run_two():
    two()  # rely on import statement in b.py


def run_three():
    global charlie  # declare the global to change it
    charlie = 40  # change the value for charlie
    print("charlie:", charlie, " --> global value changed in a.py run_three()")


def run_three_again():  # print charlie again from b.py
    three()


def run_four():  # re import charlie in b.py
    four()


if __name__ == "__main__":  # prevent the code from being executed when b.py imports a.py
    run_one()  # run through all the functions in a.py
    run_two()
    run_three()
    run_three_again()
    run_four()

Also:

from a import *  # import all from a.py


def one(alpha):
    print("alpha:  ", alpha, " --> global passed as argument in one()")


def two():
    print("bravo:  ", bravo, " --> global imported from a.py in two()")


def three():
    print("charlie:", charlie, " --> global imported from a.py in three() but is not changed")


def four():
    from a import charlie  # re import charlie from a.py
    print("charlie:", charlie, " --> global re-imported in four() but does not change")

The output from the print statements are below:

alpha:   10  --> global passed as argument in one()
bravo:   20  --> global imported from a.py in two()
charlie: 40  --> global value changed in a.py run_three()
charlie: 15  --> global imported from a.py in three() but is not changed
charlie: 15  --> global re-imported in four() but does not change
Kandis answered 25/4, 2021 at 3:10 Comment(0)
I
-9

Just put your globals in the file you are importing.

Indissoluble answered 31/10, 2017 at 10:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.