所以我有两个不同的文件:
file1.py
from file2 import *
foo = "bar";
test = SomeClass();
file2.py
class SomeClass :
def __init__ (self):
global foo;
print foo;
但是我似乎无法让file2识别来自file1的变量,即使它已经导入到file1中。如果以某种方式可行,这将是非常有用的。
答案 0 :(得分:43)
在file2
中导入file1.py
会使file2
中绑定的全局(即模块级别)名称可用于file1
中的以下代码 - 唯一的此类名称为{ {1}}。 不执行相反的操作:当SomeClass
导入file1
时,file2
中的代码无法用于file1
中的代码。即使你以正确的方式导入正确的方式(file2
,而不是你正在做的那种可怕的,可怕的方式)(如果太阳下的每个人都忘记了它的存在),情况也是如此。构建import file2
,生活将所以对每个人都好得多。)
显然,您希望将from ... import *
中定义的全局名称用于file1
和中的代码,反之亦然。这被称为“循环依赖”,并且是一个可怕的想法(在Python或其他任何地方)。
所以,我不是要向你展示难以置信的脆弱,通常难以维护的黑客(在某种程度上相似)Python中的循环依赖,我宁愿讨论你可以避免这种可怕的结构。
例如,您可以将第三个模块中的两个模块都需要可用的全局名称(例如file2
),以继续您的命名连胜;-)并导入第三个将模块分配到其他两个模块中file3.py
和import file3
中的file1
,然后使用file2
等,即限定名称,为了从其他模块中的任何一个或两个模块访问或设置这些全局名称,不裸名称。)
当然,如果你澄清(通过编辑你的Q)确切地为什么你认为你需要一个周期性的依赖(只是一个简单的预测:无论是什么让你),可以提供越来越多的具体帮助认为你需要一个周期性的依赖,你错了; - )。
答案 1 :(得分:11)
写作时
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 *
)尽管我建议您仔细考虑是否确实需要这样做。从另一个模块中更改一个模块的变量并不常见。
答案 2 :(得分:9)
from file2 import *
正在制作副本。你想这样做:
import file2
print file2.foo
print file2.SomeClass()
答案 3 :(得分:4)
global
在Python中有点用词不当,module_namespace
会更具描述性。
foo
的完全限定名称是file1.foo
,并且最好避免全局声明,因为通常有更好的方法来完成您想要做的事情。 (我无法从你的玩具示例中分辨出你想做什么。)
答案 4 :(得分:1)
搜索后,我得到了以下提示:https://instructobit.com/tutorial/108/How-to-share-global-variables-between-files-in-Python
关键是:如果激活了某个功能,则打开该功能以调用设置为全局的variabel。
然后从该文件再次导入variabel。
我给你一个困难的例子,这样你就可以理解:
文件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)
文件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)
这就是调用函数中设置的全局变量的方式。干杯 别忘了给予信用
答案 5 :(得分:0)
我得出的结论是,您可以导入全局变量,但一旦导入就无法更改它们。唯一的例外是如果您将它们作为参数传递。我很想在这方面出错,所以让我知道是否有办法有效地重新导入更新的全局变量。下面的两个代码将运行。
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 arguement 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
答案 6 :(得分:0)
当我按照@robertspierre 的想法进行测试时,将所有全局变量放在一个 glv.py 文件中,然后将其导入到其他使用它的文件中,下面给出了演示代码,希望对您有所帮助:
># glv.py
glvB = True
glvA = 100
glvS = "tiger"
glvList = [1, 2, 3]
glvTuple = (1, "a")
glvDict = {"Name": "tiger", "age": 100}
# 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}
# 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}
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
结果是:
*****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 :(得分:-1)
将您的全局变量放入要导入的文件中。
答案 8 :(得分:-2)
所有给出的答案都是错误的。在单独的文件中将函数内的变量全局化是不可能的。