来自不同文件的全局变量 Python

2025-03-20 08:46:00
admin
原创
38
摘要:问题描述:所以我有两个不同的文件,有点像这样:文件1.pyfrom file2 import * foo = "bar" test = SomeClass() 文件2.pyclass SomeClass : def __init__ (self): global f...

问题描述:

所以我有两个不同的文件,有点像这样:

文件1.py

from file2 import *
foo = "bar"
test = SomeClass()

文件2.py

class SomeClass :
    def __init__ (self):
        global foo
        print foo

但是我似乎无法让 file2 识别来自 file1 的变量,即使它已经导入到 file1 中。如果能以某种方式实现这一点,那将非常有帮助。


解决方案 1:

导入使file2file1.py绑定的全局(即模块级别)名称file2可用于 中的以下代码file1——唯一这样的名称是SomeClass。它不会相反的事情:在导入时,中定义的名称file1不会提供给 中的代码。即使您以正确的方式(如@nate正确推荐的那样)而不是以您正在执行的方式导入,情况也是如此。file2`file1file2import file2`

显然,您希望使 中定义的全局名称file1可供 中的代码使用file2 反之亦然。这被称为“循环依赖”,通常不建议这样做。

讨论避免循环依赖的方法通常更有用。

例如,您可以将需要对两个模块都可用的全局名称放在第三个模块中(例如file3.py,以继续您的命名连续性;-),并将第三个模块导入到其他两个模块中(import file3在和中file1file2然后使用file3.foo等,即限定名称,用于从其他一个或两个模块访问或设置这些全局名称,而不是裸名称)。

当然,如果您通过编辑您的问题明确说明您认为需要循环依赖的原因,则可以提供更多更具体的帮助。请注意,这通常不是正确的答案。

解决方案 2:

当你写作时

from file2 import *

它实际上将中定义的名称复制file2到 的命名空间中。因此,如果您通过以下方式file1重新分配 中的这些名称file1

foo = "bar"

例如,它只会在 中进行更改file1,而不会在 中进行更改file2。请注意,如果您要更改的属性foo,例如通过执行

foo.blah = "bar"

那么该更改将反映在中file2,因为您正在修改名称引用的现有对象foo,而不是用新对象替换它。

您可以通过执行以下操作来获得想要的效果file1.py

import file2
file2.foo = "bar"
test = SomeClass()

(请注意,您应该删除from foo import *)尽管我建议您仔细考虑一下是否真的需要这样做。在一个模块内更改另一个模块的变量并不常见。

解决方案 3:

from file2 import *正在制作副本。您想要执行以下操作:

import file2
print file2.foo
print file2.SomeClass()

解决方案 4:

global在 Python 中有点用词不当,module_namespace但更具描述性。

foo最好避免使用is的完全限定名称file1.foo和全局语句,因为通常有更好的方法来完成您想要做的事情。(我无法从您的玩具示例中判断您想要做什么。)

解决方案 5:

搜索后,我得到了这个线索:https://instructobit.com/tutorial/108/How-to-share-global-variables-between-files-in-Python

关键是:如果某个功能被激活,则打开该功能来调用设置为全局的变量。

然后从该文件再次导入变量。

我给你一个困难的例子以便你能够理解:

文件 chromy.py

from selenium import webdriver
from selenium.webdriver.chrome.options import Options

def opennormal():
    global driver
    options = Options()
    driver = webdriver.Chrome(chrome_options=options)

def gotourl(str):
    url = str
    driver.get(url)

文件测试器.py

from chromy import * #this command call all function in chromy.py, but the 'driver' variable in opennormal function is not exists yet. run: dir() to check what you call.

opennormal() #this command activate the driver variable to global, but remember, at the first import you not import it

#then do this, this is the key to solve:
from chromy import driver #run dir() to check what you call and compare with the first dir() result.

#because you already re-import the global that you need, you can use it now

url = 'https://www.google.com'
gotourl(url)

这就是调用函数中设置的全局变量的方式。欢呼,别忘了给予赞扬

解决方案 6:

我按照@robertspierre 的想法进行测试,将所有全局变量放在 glv.py 文件中,然后将其导入到使用它的其他文件中,演示代码如下,希望对您有所帮助:

  1. 全局变量文件glv.py:

# glv.py
glvB = True
glvA = 100
glvS = "tiger"
glvList = [1, 2, 3]
glvTuple = (1, "a")
glvDict = {"Name": "tiger", "age": 100}
  1. sub1.py,这是一个将导入 glv.py 文件的文件。定义了两个函数来显示和更改 glv.py 中的全局变量数据,showData() 和 changeData(),

# sub1.py
import glv


def showData():
    print(f"*****glv in sub1*****
"
          f"glvB={glv.glvB}
"
          f"glvA={glv.glvA}
"
          f"glvS={glv.glvS}
"
          f"glvList={glv.glvList}
"
          f"glvTuple={glv.glvTuple}
"
          f"glvDict={glv.glvDict}
")


def changeData():
    glv.glvB = False
    glv.glvA = 200
    glv.glvS = "bactone"
    glv.glvList = [4, 5, 6]
    glv.glvTuple = (2, "b")
    glv.glvDict = {"Name": "bactone", "age": 0}
  1. sub2.py 是另一个文件:

# sub2.py

import glv


def showData():
    print(f"*****glv in sub2*****
"
          f"glvB={glv.glvB}
"
          f"glvA={glv.glvA}
"
          f"glvS={glv.glvS}
"
          f"glvList={glv.glvList}
"
          f"glvTuple={glv.glvTuple}
"
          f"glvDict={glv.glvDict}
")


def changeData():
    glv.glvB = True
    glv.glvA = 300
    glv.glvS = "bactone"
    glv.glvList = [7, 8, 9]
    glv.glvTuple = (3, "c")
    glv.glvDict = {"Name": "bactone1", "age": 10}
  1. 最后我们在main.py中测试全局变量:

import glv
import sub1
import sub2


def showData():
    print(f"*****initial global variable values*****
"
          f"glvB={glv.glvB}
"
          f"glvA={glv.glvA}
"
          f"glvS={glv.glvS}
"
          f"glvList={glv.glvList}
"
          f"glvTuple={glv.glvTuple}
"
          f"glvDict={glv.glvDict}
")


if __name__ == "__main__":

    showData()  # show initial global variable
    sub1.showData()  # show global variable in sub1
    sub1.changeData()  # change global variable in sub1
    sub2.showData()  # show global variable in sub2
    sub2.changeData()  # change global variable in sub2
    sub1.showData()  # show global variable in sub1 again

结果如下:

*****initial global variable values*****
glvB=True
glvA=100
glvS=tiger
glvList=[1, 2, 3]
glvTuple=(1, 'a')
glvDict={'Name': 'tiger', 'age': 100}

*****glv in sub1*****
glvB=True
glvA=100
glvS=tiger
glvList=[1, 2, 3]
glvTuple=(1, 'a')
glvDict={'Name': 'tiger', 'age': 100}

*****glv in sub2*****
glvB=False
glvA=200
glvS=bactone
glvList=[4, 5, 6]
glvTuple=(2, 'b')
glvDict={'Name': 'bactone', 'age': 0}

*****glv in sub1*****
glvB=True
glvA=300
glvS=bactone
glvList=[7, 8, 9]
glvTuple=(3, 'c')
glvDict={'Name': 'bactone1', 'age': 10}

我们可以看到各种数据类型都起作用,并且全局变量的变化会自动重新加载。

解决方案 7:

我得出的结论是,你可以导入全局变量,但导入后就无法更改它们。唯一的例外是将它们作为参数传递。我很希望我错了,所以如果有办法有效地重新导入更新后的全局变量,请告诉我。下面的两个代码将运行。

from b import *  # import all from b.py

global alpha  # declare globals
global bravo
global charlie

alpha = 10  # assign values to globals
bravo = 20
charlie = 15


def run_one():
    one(alpha)  # pass the global to b.py


def run_two():
    two()  # rely on import statement in b.py


def run_three():
    global charlie  # declare the global to change it
    charlie = 40  # change the value for charlie
    print("charlie:", charlie, " --> global value changed in a.py run_three()")


def run_three_again():  # print charlie again from b.py
    three()


def run_four():  # re import charlie in b.py
    four()


if __name__ == "__main__":  # prevent the code from being executed when b.py imports a.py
    run_one()  # run through all the functions in a.py
    run_two()
    run_three()
    run_three_again()
    run_four()

还:

from a import *  # import all from a.py


def one(alpha):
    print("alpha:  ", alpha, " --> global passed as argument in one()")


def two():
    print("bravo:  ", bravo, " --> global imported from a.py in two()")


def three():
    print("charlie:", charlie, " --> global imported from a.py in three() but is not changed")


def four():
    from a import charlie  # re import charlie from a.py
    print("charlie:", charlie, " --> global re-imported in four() but does not change")

打印语句的输出如下:

alpha:   10  --> global passed as argument in one()
bravo:   20  --> global imported from a.py in two()
charlie: 40  --> global value changed in a.py run_three()
charlie: 15  --> global imported from a.py in three() but is not changed
charlie: 15  --> global re-imported in four() but does not change

解决方案 8:

只需将全局变量放入要导入的文件中即可。

相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   2482  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1533  
  PLM(产品生命周期管理)项目对于企业优化产品研发流程、提升产品质量以及增强市场竞争力具有至关重要的意义。然而,在项目推进过程中,范围蔓延是一个常见且棘手的问题,它可能导致项目进度延迟、成本超支以及质量下降等一系列不良后果。因此,有效避免PLM项目范围蔓延成为项目成功的关键因素之一。以下将详细阐述三大管控策略,助力企业...
plm系统   0  
  PLM(产品生命周期管理)项目管理在企业产品研发与管理过程中扮演着至关重要的角色。随着市场竞争的加剧和产品复杂度的提升,PLM项目面临着诸多风险。准确量化风险优先级并采取有效措施应对,是确保项目成功的关键。五维评估矩阵作为一种有效的风险评估工具,能帮助项目管理者全面、系统地评估风险,为决策提供有力支持。五维评估矩阵概述...
免费plm软件   0  
  引言PLM(产品生命周期管理)开发流程对于企业产品的全生命周期管控至关重要。它涵盖了从产品概念设计到退役的各个阶段,直接影响着产品质量、开发周期以及企业的市场竞争力。在当今快速发展的科技环境下,客户对产品质量的要求日益提高,市场竞争也愈发激烈,这就使得优化PLM开发流程成为企业的必然选择。缺陷管理工具和六西格玛方法作为...
plm产品全生命周期管理   0  
热门文章
项目管理软件有哪些?
曾咪二维码

扫码咨询,免费领取项目管理大礼包!

云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用