我对全局变量的工作原理有点困惑。我有一个大项目,大约有50个文件,我需要为所有这些文件定义全局变量。

我所做的就是在项目main.py文件中定义它们,如下所示:

# ../myproject/main.py

# Define global myList
global myList
myList = []

# Imports
import subfile

# Do something
subfile.stuff()
print(myList[0])

我试图在subfile.py中使用myList,如下所示

# ../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,这是我不想做的。


当前回答

请参阅Python关于跨模块共享全局变量的文档:

在单个程序中跨模块共享信息的规范方法是创建一个特殊的模块(通常称为config或cfg)。 config.py: x = 0 # 'x'配置设置的默认值 在应用程序的所有模块中导入配置模块;然后,模块就可以作为全局名称使用。 main.py: 导入配置 打印(config.x)


一般情况下,不要使用from modulename import *。这样做会使导入器的名称空间变得混乱,并使linter更难检测到未定义的名称。

其他回答

我只是偶然看到这篇文章,并考虑发布我的解决方案,以防任何人遇到和我一样的情况,在开发的程序中有相当多的文件,而你没有时间考虑模块的整个导入序列(如果你从一开始就没有考虑到这一点,比如我)。

在这种情况下,在你初始化全局变量的脚本中,简单地编写一个类,如下所示:

class My_Globals:
  def __init__(self):
    self.global1 = "initial_value_1"
    self.global2 = "initial_value_2"
    ...

然后使用,而不是脚本中初始化全局变量的那行,而不是

global1 = "initial_value_1"

use

globals = My_Globals()

然后,我能够通过检索/更改这些全局变量的值

globals.desired_global

in any script, and these changes were automatically also applied to all the other scripts using them. All worked now, by using the exact same import statements which previously failed, due to the problems mentioned in this post / discussion here. I simply thought of global object's properties being changing dynamically without the need of considering / changing any import logic, in comparison to simple importing of global variables, and that definitely was the quickest and easiest (for later access) approach to solve this kind of problem for me.

Hai Vu的回答很好,只有一个评论:

如果你在其他模块中使用全局变量,并且你想动态设置全局变量,请注意在设置全局变量后导入其他模块,例如:

# 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

使用from your_file import *可以解决这个问题。它定义了所有内容,使其全局可用(当然,导入中的局部变量除外)。

例如:

##test.py:

from pytest import *

print hello_world

and:

##pytest.py

hello_world="hello world!"

请参阅Python关于跨模块共享全局变量的文档:

在单个程序中跨模块共享信息的规范方法是创建一个特殊的模块(通常称为config或cfg)。 config.py: x = 0 # 'x'配置设置的默认值 在应用程序的所有模块中导入配置模块;然后,模块就可以作为全局名称使用。 main.py: 导入配置 打印(config.x)


一般情况下,不要使用from modulename import *。这样做会使导入器的名称空间变得混乱,并使linter更难检测到未定义的名称。

你可以把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])

And:

# ../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")