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


当前回答

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

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

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.

其他回答

基于上面的答案和链接,我创建了一个名为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多模块程序中测试,但到目前为止,它工作得很完美。

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

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

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

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.

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

例如:

##test.py:

from pytest import *

print hello_world

and:

##pytest.py

hello_world="hello world!"

当您从配置导入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()方法来解决它。

但问题在于。