在文件之间使用全局变量?

174 python share globals

我对全局变量如何工作感到困惑.我有一个大型项目,大约有50个文件,我需要为所有这些文件定义全局变量.

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

# ../myproject/main.py

# Define global myList
global myList
myList = []

# Imports
import subfile

# Do something
subfile.stuff()
print(myList[0])
Run Code Online (Sandbox Code Playgroud)

我想用myListsubfile.py,如下

# ../myproject/subfile.py

# Save "hey" into myList
def stuff():
    globals()["myList"].append("hey")
Run Code Online (Sandbox Code Playgroud)

我试过的另一种方式,但也没有用

# ../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])
Run Code Online (Sandbox Code Playgroud)

在里面subfile.py我有这个:

# ../myproject/subfile.py

# Import globfile
import globfile

# Save "hey" into myList
def stuff():
    globfile.myList.append("hey")
Run Code Online (Sandbox Code Playgroud)

但同样,它没有奏效.我该如何实现呢?我明白它不能那样工作,当两个文件真的不知道对方(好子文件不知道主要),但我想不出怎么做,不使用io写或pickle,我不想这样做.

Hai*_* Vu 280

问题是您定义myListmain.py,但subfile.py需要使用它.这是一个解决此问题的简洁方法:将所有全局变量移动到文件,我调用此文件settings.py.该文件负责定义全局变量并初始化它们:

# settings.py

def init():
    global myList
    myList = []
Run Code Online (Sandbox Code Playgroud)

接下来,您subfile可以导入全局变量:

# subfile.py

import settings

def stuff():
    settings.myList.append('hey')
Run Code Online (Sandbox Code Playgroud)

请注意,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
Run Code Online (Sandbox Code Playgroud)

这样,您可以实现目标,同时避免多次初始化全局变量.

  • 我喜欢一般的方法,但不喜欢整个`init()`的东西.模块仅在第一次导入时进行评估,因此在模块主体中初始化这些变量是完全可以的. (34认同)
  • +1柯克:我同意.但是,我的方法可以防止其他模块在主程序启动之前修改globals.myList的情况. (16认同)
  • 您应该将其称为全局变量以外的其他内容,这是一个内置名称.PyLint发出警告:"重新定义内置'全局'(重新定义内置)" (2认同)

Oga*_*zoh 79

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

在单个程序中跨模块共享信息的规范方法是创建一个特殊模块(通常称为config或cfg).

config.py:

x = 0   # Default value of the 'x' configuration setting
Run Code Online (Sandbox Code Playgroud)

在应用程序的所有模块中导入配置模块; 然后该模块可用作全局名称.

main.py:

import config
print(config.x)
Run Code Online (Sandbox Code Playgroud)

要么

from config import x
print(x)
Run Code Online (Sandbox Code Playgroud)

这也可以让你动态设置这样一个变量:

x = 0   # Default value of the 'x' configuration setting
Run Code Online (Sandbox Code Playgroud)

在一般情况下,不要使用MODULENAME进口*.这样做会使导入器的命名空间变得混乱,并且使得连接器更难以检测未定义的名称.

  • 请注意,您不能使用“from config import x”设置“x”,只能使用“import config” (13认同)
  • 这似乎比接受的答案更干净。 (3认同)

jsb*_*eno 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])
Run Code Online (Sandbox Code Playgroud)

和:

# ../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")
Run Code Online (Sandbox Code Playgroud)

  • ha 乍一看是这样的,不是吗?def stuff() 中发生的事情是导入文件在加载时不运行..它只在 stuff() 函数被调用时运行。所以从 main 开始,我们导入子文件,然后调用 subfile.stuff() 然后导入 main...没有循环,只需在 main 中导入一次。请参阅 subfile.py 示例中有关导入周期的注释。 (3认同)
  • 哇,通常人们会期望相互导入的两个文件进入无限循环。 (2认同)

IT *_*nja 12

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

例如:

##test.py:

from pytest import *

print hello_world
Run Code Online (Sandbox Code Playgroud)

和:

##pytest.py

hello_world="hello world!"
Run Code Online (Sandbox Code Playgroud)

  • 不要进口*.您的全局变量将不再保持同步.每个模块都会收到自己的副本.更改一个文件中的变量不会反映在另一个文件中.它也在https://docs.python.org/2/faq/programming.html#how-do-i-share-global-variables-across-modules中被警告 (15认同)
  • 我个人不惜一切代价避免使用`import*`,因此引用是明确的(而不是混淆),此外,当你真的在任何模块中使用所有"`*`"引用时? (5认同)
  • 除非您分配给一个这样的变量 (4认同)

las*_*boy 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
Run Code Online (Sandbox Code Playgroud)