我对全局变量如何运作感到困惑。我有一个大型项目,大约有50个文件,我需要为所有这些文件定义全局变量。
我所做的是在我的项目main.py
文件中定义它们,如下所示:
# ../myproject/main.py
# Define global myList
global myList
myList = []
# Imports
import subfile
# Do something
subfile.stuff()
print(myList[0])
我正在myList
中使用subfile.py
,如下所示
# ../myproject/subfile.py
# Save "hey" into myList
def stuff():
globals()["myList"].append("hey")
我试过的另一种方式,但无法正常工作
# ../myproject/main.py
# Import globfile
import globfile
# Save myList into globfile
globfile.myList = []
# Import subfile
import subfile
# Do something
subfile.stuff()
print(globfile.myList[0])
在subfile.py
里面我有这个:
# ../myproject/subfile.py
# Import globfile
import globfile
# Save "hey" into myList
def stuff():
globfile.myList.append("hey")
但同样,它没有用。我该如何实现呢?我明白它不能那样工作,当两个文件真的不知道对方(好子文件不知道主要),但我想不出怎么做,不使用io写或pickle,我不想这样做。
答案 0 :(得分:252)
问题是您从myList
定义了main.py
,但subfile.py
需要使用它。以下是解决此问题的简洁方法:将所有全局变量移动到文件中,我将此文件称为settings.py
。该文件负责定义全局变量并初始化它们:
# settings.py
def init():
global myList
myList = []
接下来,您的subfile
可以导入全局变量:
# subfile.py
import settings
def stuff():
settings.myList.append('hey')
请注意,subfile
不会调用init()
- 该任务属于main.py
:
# main.py
import settings
import subfile
settings.init() # Call only once
subfile.stuff() # Do stuff with global var
print settings.myList[0] # Check the result
这样,您可以实现目标,同时避免多次初始化全局变量。
答案 1 :(得分:20)
您可以将Python全局变量视为“模块”变量 - 因此它们比C中的传统“全局变量”更有用。
全局变量实际上是在模块的__dict__
中定义的,可以从模块外部作为模块属性进行访问。
所以,在你的例子中:
# ../myproject/main.py
# Define global myList
# global myList - there is no "global" declaration at module level. Just inside
# function and methods
myList = []
# Imports
import subfile
# Do something
subfile.stuff()
print(myList[0])
和
# ../myproject/subfile.py
# Save "hey" into myList
def stuff():
# You have to make the module main available for the
# code here.
# Placing the import inside the function body will
# usually avoid import cycles -
# unless you happen to call this function from
# either main or subfile's body (i.e. not from inside a function or method)
import main
main.mylist.append("hey")
答案 2 :(得分:12)
使用from your_file import *
可以解决您的问题。它定义了所有内容,以便全局可用(当然,导入中的局部变量除外)。
例如:
##test.py:
from pytest import *
print hello_world
和
##pytest.py
hello_world="hello world!"
答案 3 :(得分:8)
Hai Vu的回答非常好,只有一条评论:
如果您在其他模块中使用global并且想要动态设置全局,请在设置全局变量后注意导入其他模块,例如:
# settings.py
def init(arg):
global myList
myList = []
mylist.append(arg)
# subfile.py
import settings
def print():
settings.myList[0]
# main.py
import settings
settings.init("1st") # global init before used in other imported modules
# Or else they will be undefined
import subfile
subfile.print() # global usage
答案 4 :(得分:4)
您的第二次尝试将完美地运行,并且实际上是处理您希望全局可用的变量名称的一种非常好的方法。但是你在最后一行有一个名字错误。这是应该如何:
# ../myproject/main.py
# Import globfile
import globfile
# Save myList into globfile
globfile.myList = []
# Import subfile
import subfile
# Do something
subfile.stuff()
print(globfile.myList[0])
看到最后一行? myList是globfile的attr,而不是子文件。这将按你的意愿工作。
麦克
答案 5 :(得分:0)
我只是碰到了这篇文章,并考虑过发布我的解决方案,以防万一有人和我处于相同的情况,开发的程序中有很多文件,而您没有时间思考整个模块的导入顺序(如果您像我一样从一开始就没有正确考虑到这一点)。
在这种情况下,在初始化全局变量的脚本中,只需编写一个如下所示的类即可:
class My_Globals:
def __init__(self):
self.global1 = "initial_value_1"
self.global2 = "initial_value_2"
...
,然后使用而不是初始化全局变量的脚本中的行代替
global1 = "initial_value_1"
使用
globals = My_Globals()
然后我可以通过以下方式检索/更改任何这些全局变量的值
globals.desired_global
在任何脚本中,这些更改也会自动应用到使用它们的所有其他脚本中。由于使用了之前在此帖子/讨论中提到的问题,因此之前使用的导入语句完全相同,现在所有这些都可以正常工作。与简单地导入全局变量相比,我只是认为全局对象的属性是动态变化的,而不需要考虑/更改任何导入逻辑,这绝对是解决此类问题的最快,最简单的方法(供以后访问)为我。
答案 6 :(得分:0)
基于上述答案和链接,我创建了一个名为 global_variables.py
的新模块:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# ==============================================================================
#
# global_variables.py - Global variables shared by all modules.
#
# ==============================================================================
USER = None # User ID, Name, GUID varies by platform
def init():
""" This should only be called once by the main module
Child modules will inherit values. For example if they contain
import global_variables as g
Later on they can reference 'g.USER' to get the user ID.
"""
global USER
import getpass
USER = getpass.getuser()
# End of global_variables.py
然后在我的主模块中我使用这个:
import global_variables as g
g.init()
在我可以使用的另一个子导入模块中:
import global_variables as g
# hundreds of lines later....
print(g.USER)
我只花了几分钟在两个不同的 Python 多模块程序中进行了测试,但到目前为止它运行良好。