我对全局变量的工作原理有点困惑。我有一个大项目,大约有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,这是我不想做的。


当前回答

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

其他回答

当您从配置导入mySharedThing时,会出现命名空间噩梦。这一点再怎么强调也不为过。

使用from in other places也可以。

你甚至可以有一个完全空的配置模块。

# my_config.py
pass
# my_other_module.py
import my_config

def doSomething():
    print(my_config.mySharedThing.message)
# main.py
from dataclasses import dataclass
from my_other_module import doSomething
import my_config

@dataclass
class Thing:
    message: str

my_config.mySharedThing = Thing('Hey everybody!')
doSomething()

结果:

$ python3 main.py
Hey everybody!

但是使用你从那里拉来的物品会让你陷入沮丧。

# my_other_module.py
from my_config import mySharedThing

def doSomething():
    print(mySharedThing.message)

结果:

$ python3 main.py
ImportError: cannot import name 'mySharedThing' from 'my_config' (my_config.py)

也许你会尝试这样修正它:

# my_config.py
mySharedThing = None

结果:

$ python3 main.py
AttributeError: 'NoneType' object has no attribute 'message'

然后您可能会找到这个页面,并尝试通过添加init()方法来解决它。

但问题在于。

您的第二次尝试将会完美地工作,这实际上是一种处理您希望全局可用的变量名的好方法。但是你在最后一行有一个名字错误。应该是这样的:

# ../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,不是subfile。这将如你所愿。

Mike

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

问题是你从main.py定义了myList,但是subfile.py需要使用它。这里有一个干净的方法来解决这个问题:将所有全局变量移动到一个文件中,我称之为settings.py。这个文件负责定义全局变量并初始化它们:

# settings.py

def init():
    global myList
    myList = []

接下来,你的子文件可以导入全局变量:

# 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

通过这种方式,可以实现目标,同时避免多次初始化全局变量。

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