【问题标题】:using global variable in python among modules in different packages在不同包中的模块之间使用python中的全局变量
【发布时间】:2016-07-07 13:35:44
【问题描述】:

我是 Python 新手,我正在尝试使用来自不同包中不同模块的包中模块的全局计数器。我想要做的是在模块中声明一个变量并将其导入不同包中的其他模块。我对这个问题做了一个简单的测试,它也在这里发生。我将所有文件放在同一个目录中(它们现在在同一个包中,但问题是一样的)。

文件glbcntmod.py:

glbcnt = 0

文件glbfuncmod.py:

from glbcntmod import glbcnt
def glbfunc():
    global glbcnt
    print 'glbcnt = ',glbcnt

文件:test.py

#!/usr/bin/env python
from glbcntmod import glbcnt
from glbfuncmod import glbfunc

loccnt = 0
def localfunc():
    print 'loccnt = ',loccnt

if __name__ == '__main__':
    glbcnt = 0
    for i in xrange(0,4):
        glbfunc()
        localfunc()
        glbcnt += 1
        loccnt += 1

当我运行 test.py 时,结果如下所示。 loccnt 正在递增,但 glbcnt 始终为 0。这是什么问题?

glbcnt =  0
loccnt =  0
glbcnt =  0
loccnt =  1
glbcnt =  0
loccnt =  2
glbcnt =  0
loccnt =  3

【问题讨论】:

标签: python python-2.7 global-variables


【解决方案1】:

这样做的方法是保留变量所在的模块作为参考:

import other_module

other_module.counter += 1

如果您在使用 counter 的任何地方都这样做,它将在模块之间具有一致的值。

这是因为每次在 Python 中对名称进行赋值时,与该名称关联的对象都会更改 -

也就是说,如果你这样做了

from othermodule import counter
counter = 1

您的counter 变量将指向与该分配不同的对象。由于数字是不可变的对象,因此还有其他问题。

但是,如果您保留原始模块,则您正在更改该模块对象中的属性 - 它的行为与任何其他 Python 对象完全相同。只要其他代码将变量作为模块的属性访问,就可以了。

【讨论】:

  • 好的,我明白了。导入模块并使用 module.variable 格式。听起来好像当我们导入一个模块时,对象的 id 并没有改变,但是当我们从一个模块中导入一个变量时,它是一个新的对象。当对象是不可变的时。是这样的吗?
  • 几乎-当您从模块导入变量时,它仍然是同一个对象-如果它是可变的(如列表),更改它将反映在其他模块上。但是,当您将该变量分配给某个东西(= 运算符,或 += 和其他不可变对象上的)时,该变量指向一个新对象 - 与原始模块无关。
【解决方案2】:

请注意,int 在 python 中是不可变的。这意味着做类似的事情

a = 0
b = a  # b = 0
b += 1  # b = 2

仍会将a 保留为0

当你做from glbcntmod import glbcnt时,这基本上等于

import glbcntmod
glbcnt = glbcntmod.glbcnt

因此,如果您随后增加 glbcnt,则只会为本地名称分配新值。原来的glbcnt没有改变。

如果要使用全局变量,则必须使用其全局名称。所以你想要使用和修改的是glbcntmod.glbcnt

【讨论】:

    【解决方案3】:

    如果您尝试从另一个模块更新全局变量,请查看以下答案:https://stackoverflow.com/a/15595447/3224629

    【讨论】:

      【解决方案4】:

      在 test.py 中:

      if __name__ == '__main__':
          glbcnt = 0
          for i in xrange(0,4):
              ...
              glbcnt += 1
      

      您在此处创建一个本地 glbcnt 变量,该变量是递增的。您的 glbfunc() 看不到此变量,因此无法打印其值。

      试试这个:

      if __name__ == '__main__':
          global glbcnt
          glbcnt = 0
          ...
      

      此外,因此,您的整个 glbcntmod.py 文件变得毫无意义。

      不是因为一个变量被声明为全局一次,它在任何地方都变成全局的。

      "global glbcnt" 仅仅意味着从这里开始,在这个范围内,任何对 glbcnt 的引用都将引用全局变量。没有任何效果适用于其他范围,即。其他模块。

      【讨论】:

      • 你看起来是对的,但是当我在 main 中添加 'global globcnt' 时,它是一样的..奇怪.. 当然我也从 main 中删除了 'glbcnt = 0'。
      • 嗨,现在我从 bueno 的回复中明白了。补充一下,在分配给 glbcnt 之前,我最初在每个函数中都使用了“global glbcnt”,但问题是当我从模块导入变量时,它是从“全局值”导入的,当我在内部声明“全局 glbcnt”时函数,它的意思是'使用导入的全局值glbcnt(但它仍然是本地的)。所以在这种情况下,我应该使用 import module.variable 格式。我是这么理解的。
      猜你喜欢
      • 1970-01-01
      • 2012-06-03
      • 1970-01-01
      • 2020-08-25
      • 1970-01-01
      • 2017-06-02
      • 1970-01-01
      • 2014-12-01
      • 1970-01-01
      相关资源
      最近更新 更多