【问题标题】:Global Variable across modules跨模块的全局变量
【发布时间】:2016-10-20 07:58:33
【问题描述】:

我在项目到期时遇到了这个问题。我的项目被设计成有多个子模块。

现在每个子模块都需要屏幕上相同项目的位置,每次程序运行时都是随机的。我认为检查一次项目的位置是个好主意(它不会改变runtime) ,并让所有模块访问该位置。(因为检查位置需要很长时间)

这就是我所做的:

.py

import Config
import sub_module

main()

def main():
    position = get_pos()
    Config.pos = position
    sub_module.click_on_item()

配置文件

pos = None

我尝试使用此代码,所以当我运行程序时,它会将config.py 模块pos 变量设置为屏幕上项目的位置。
这段代码工作正常但是当我尝试在子模块中使用它时:

sub_module.py

import Config

def click_on_item():
    click(Config.pos)

它将值重置为 None ,因为它重新运行 Config 模块代码。
这个问题有一个优雅的解决方案吗?我不能让立场作为 的论据,因为我的情况要复杂得多。

我能想到的一个解决方案是写入磁盘,然后重新读取,但速度不快。

感谢您的帮助。

2 编辑:

我的项目是多包,有问题 这是目录树:

mainPackage:
    __init__.py
    Config.py
    main.py
    b.py
    Packages:
        Package_A:
            __init__.py
            a.py

main.py

import Config
from Packages.Package_A import a
import b

def main():
    Config.Position = (124, 586)
    a.print_val()
    b.print_val()

if __name__ == '__main__':
    main()

配置

Position = None

b.py

import Config

def print_val():
    print Config.Position

a.py

from mainPackage import Config

def print_val():
    print Config.Position

输出

None -> from Package_A
(124, 586) -> from b.py

很抱歉给您带来不便,因为我不知道是什么导致了问题,我的兴趣是多包全局变量。

【问题讨论】:

  • 你的问题的前提,如这一行所示:“它将值重置为 None ,因为它重新运行 Config 模块代码”是完全错误的。 Python 不会重新运行多次导入的模块。您的原始代码应该如图所示工作。你确定你没有在你真正的sub_module.py 中做from Config import pos 吗?因为这确实在sub_module 的导入时间而不是在调用click_on_items 函数时获取pos 的值。 (您还显示 main() 在定义之前被调用。)
  • 每次导入都会重新运行一次吗?是的,我只是在导入配置。上面的代码只是一个示例,不是实际代码
  • @Padraic Cunningham 是的,这就是我想要做的,但它在我的代码中不起作用——我会再看看
  • 写一个显示问题的工作示例!您犯了一些我们可以帮助您解决的小错误——但如果您只是在倾倒垃圾、不工作的示例,而您自己并不想自己运行,那么您就不会犯了。我在您的 main.py 中注意到您在定义它之前调用了main。那是行不通的。我们如何才能发现这么多人的真正错误?!

标签: python python-module


【解决方案1】:

Config.py 只会在导入时在您的应用程序中初始化一次,pos 最初将是 None

main.py 然后设置它,所有其他模块都可以通过Config.pos 访问pos


Config.py

# Initial value
pos = None

main.py

import Config
import sub_module

def main():
    position = get_pos()
    Config.pos = position
    sub_module.click_on_item()

您的其余文件可以保持原样。

更新

正如@tdelaney 在他的回答中提到的那样。

改变

from mainPackage import Config

import Config

避免另一个Config

【讨论】:

  • 看看我的例子
  • @DavidBarishev 您已将Config.py 中的pos 重命名为Position,并尝试访问已不存在的Config.pos
  • 对不起,我添加了另一个例子来说明我的情况,我终于查明了问题,请看一下
  • @DavidBarishev 查看 tdelaney 的回答。
【解决方案2】:

问题出在 a.py 中:from mainPackage import Config。您从包中进行了绝对导入,并最终导入了 Config 两次。 Python 只导入一个模块一次,但在您的情况下,您使用了两个不同的名称(在某些文件中为 Config,在其他文件中为 mainPackage.Config),这混淆了 python 并且它两次导入模块 - 一次通过包相对导入,一次通过绝对导入进口。将print "Importing Config" 添加到Config.py,你会看到它打印了两次。

只需将 a.py 更改为 import Config,一切都会好起来的。

【讨论】:

    【解决方案3】:

    对于您的每个模块,使用“pos”参数定义您的函数/类。

    模块 A.py

    def foo(pos):
        click(pos)
    

    模块 main.py

    def main():
        position = get_pos()
        A.foo(position)
    

    一般情况下,不要使用全局变量。

    【讨论】:

    • 感谢您的快速解决方案,这是一个可行的选择,但有没有办法将其添加为参数?因为没那么简单
    • @DavidBarishev 然后给出一个minimal reproducible example,它实际上反映了您正在尝试做的事情 - 全局变量不太可能是正确的解决方案。
    猜你喜欢
    • 2017-06-02
    • 2014-02-18
    • 1970-01-01
    • 1970-01-01
    • 2016-02-10
    • 2017-04-30
    • 2015-03-07
    • 2016-09-15
    相关资源
    最近更新 更多