来自不同文件的全局变量 Python
- 2025-03-20 08:46:00
- admin 原创
- 37
问题描述:
所以我有两个不同的文件,有点像这样:
文件1.py
from file2 import *
foo = "bar"
test = SomeClass()
文件2.py
class SomeClass :
def __init__ (self):
global foo
print foo
但是我似乎无法让 file2 识别来自 file1 的变量,即使它已经导入到 file1 中。如果能以某种方式实现这一点,那将非常有帮助。
解决方案 1:
导入使file2
中file1.py
绑定的全局(即模块级别)名称file2
可用于 中的以下代码file1
——唯一这样的名称是SomeClass
。它不会做相反的事情:在导入时,中定义的名称file1
不会提供给 中的代码。即使您以正确的方式(如@nate正确推荐的那样)而不是以您正在执行的方式导入,情况也是如此。file2
`file1file2
import file2`
显然,您希望使 中定义的全局名称file1
可供 中的代码使用file2
,反之亦然。这被称为“循环依赖”,通常不建议这样做。
讨论避免循环依赖的方法通常更有用。
例如,您可以将需要对两个模块都可用的全局名称放在第三个模块中(例如file3.py
,以继续您的命名连续性;-),并将第三个模块导入到其他两个模块中(import file3
在和中file1
,file2
然后使用file3.foo
等,即限定名称,用于从其他一个或两个模块访问或设置这些全局名称,而不是裸名称)。
当然,如果您通过编辑您的问题明确说明您认为需要循环依赖的原因,则可以提供更多更具体的帮助。请注意,这通常不是正确的答案。
解决方案 2:
当你写作时
from file2 import *
它实际上将中定义的名称复制file2
到 的命名空间中。因此,如果您通过以下方式file1
重新分配 中的这些名称file1
foo = "bar"
例如,它只会在 中进行更改file1
,而不会在 中进行更改file2
。请注意,如果您要更改的属性foo
,例如通过执行
foo.blah = "bar"
那么该更改将反映在中file2
,因为您正在修改名称引用的现有对象foo
,而不是用新对象替换它。
您可以通过执行以下操作来获得想要的效果file1.py
:
import file2
file2.foo = "bar"
test = SomeClass()
(请注意,您应该删除from foo import *
)尽管我建议您仔细考虑一下是否真的需要这样做。在一个模块内更改另一个模块的变量并不常见。
解决方案 3:
from file2 import *
正在制作副本。您想要执行以下操作:
import file2
print file2.foo
print file2.SomeClass()
解决方案 4:
global
在 Python 中有点用词不当,module_namespace
但更具描述性。
foo
最好避免使用is的完全限定名称file1.foo
和全局语句,因为通常有更好的方法来完成您想要做的事情。(我无法从您的玩具示例中判断您想要做什么。)
解决方案 5:
搜索后,我得到了这个线索:https://instructobit.com/tutorial/108/How-to-share-global-variables-between-files-in-Python
关键是:如果某个功能被激活,则打开该功能来调用设置为全局的变量。
然后从该文件再次导入变量。
我给你一个困难的例子以便你能够理解:
文件 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)
文件测试器.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)
这就是调用函数中设置的全局变量的方式。欢呼,别忘了给予赞扬
解决方案 6:
我按照@robertspierre 的想法进行测试,将所有全局变量放在 glv.py 文件中,然后将其导入到使用它的其他文件中,演示代码如下,希望对您有所帮助:
全局变量文件glv.py:
# glv.py
glvB = True
glvA = 100
glvS = "tiger"
glvList = [1, 2, 3]
glvTuple = (1, "a")
glvDict = {"Name": "tiger", "age": 100}
sub1.py,这是一个将导入 glv.py 文件的文件。定义了两个函数来显示和更改 glv.py 中的全局变量数据,showData() 和 changeData(),
# sub1.py
import glv
def showData():
print(f"*****glv in sub1*****
"
f"glvB={glv.glvB}
"
f"glvA={glv.glvA}
"
f"glvS={glv.glvS}
"
f"glvList={glv.glvList}
"
f"glvTuple={glv.glvTuple}
"
f"glvDict={glv.glvDict}
")
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}
sub2.py 是另一个文件:
# sub2.py
import glv
def showData():
print(f"*****glv in sub2*****
"
f"glvB={glv.glvB}
"
f"glvA={glv.glvA}
"
f"glvS={glv.glvS}
"
f"glvList={glv.glvList}
"
f"glvTuple={glv.glvTuple}
"
f"glvDict={glv.glvDict}
")
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}
最后我们在main.py中测试全局变量:
import glv
import sub1
import sub2
def showData():
print(f"*****initial global variable values*****
"
f"glvB={glv.glvB}
"
f"glvA={glv.glvA}
"
f"glvS={glv.glvS}
"
f"glvList={glv.glvList}
"
f"glvTuple={glv.glvTuple}
"
f"glvDict={glv.glvDict}
")
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
结果如下:
*****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}
我们可以看到各种数据类型都起作用,并且全局变量的变化会自动重新加载。
解决方案 7:
我得出的结论是,你可以导入全局变量,但导入后就无法更改它们。唯一的例外是将它们作为参数传递。我很希望我错了,所以如果有办法有效地重新导入更新后的全局变量,请告诉我。下面的两个代码将运行。
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()
还:
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")
打印语句的输出如下:
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
解决方案 8:
只需将全局变量放入要导入的文件中即可。
扫码咨询,免费领取项目管理大礼包!