Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/360.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python模块中的全局变量会自动重置_Python_Python 3.x - Fatal编程技术网

Python模块中的全局变量会自动重置

Python模块中的全局变量会自动重置,python,python-3.x,Python,Python 3.x,我有一个用Python 3.5编写的程序的一部分,从测试前两个模块开始。我设法隔离了其中一个模块中的一个问题,其中两个全局变量似乎在毫无原因地切换回其原始值。其中一个全局变量(event\u count)仅在单个函数中使用(grep显示字符串“event\u count”不会出现在我的*.py文件中的任何其他地方),但变量的值在调用函数之间会发生变化。如果我为这个模块中的另一个全局变量添加print语句,它也会在同一时刻恢复为其原始值。将event\u count移动到另一个模块(将其替换为se

我有一个用Python 3.5编写的程序的一部分,从测试前两个模块开始。我设法隔离了其中一个模块中的一个问题,其中两个全局变量似乎在毫无原因地切换回其原始值。其中一个全局变量(
event\u count
)仅在单个函数中使用(grep显示字符串“event\u count”不会出现在我的*.py文件中的任何其他地方),但变量的值在调用函数之间会发生变化。如果我为这个模块中的另一个全局变量添加print语句,它也会在同一时刻恢复为其原始值。将
event\u count
移动到另一个模块(将其替换为
sensorlogic.event\u count
in
eventcount()
中的
event\u count
并将初始化移动到另一个模块)会使该行为消失,因此我有一个解决方案,但无法理解

以下是模块
传感器评估
中使用
事件计数的所有代码:

event_count = 0

def eventcount(increment):
    global event_count
    print("entering eventcount, increment =", increment,
          ", event_count =", event_count)
    event_count += increment
    print("leaving eventcount, event_count =", event_count)
    return event_count
如果我运行以下代码段:

    e.setvalue(1)
    print("I am at marker #1")
    eventcount(0)
(在
e.setvalue()
中的最后一个操作是调用
eventcount(0)
)它生成以下输出:

entering eventcount, increment = 0 , event_count = 4
leaving eventcount, event_count = 4
I am at marker #1
entering eventcount, increment = 0 , event_count = 0
leaving eventcount, event_count = 0
我曾尝试将这两个模块缩减到合理的大小,但当我这样做时,问题就一直在消失。我会继续努力的。因为我以前从未使用过Python3,并且只有一点Python2.7的经验,所以我假设我在做一些愚蠢的事情,我只是不知道是什么

我相信我的例子不同于一些相关的帖子,因为变量
event\u count
是全局变量,所以它是静态的。它仅用于此单一功能。字符串“event_count”不会出现在此模块或任何其他模块中的任何其他位置


在多次编辑/重新运行迭代之后,我有一个可管理的小示例来演示正在发生的事情。它涉及两个模块,共8行代码。第一个模块,
a.py
,是
\uuuu main\uuuu

import b
c = 0
if __name__ == '__main__': 
    b.init()
    print("c =", c)
第二个模块是
b.py

import a
def init():
    a.c = 1
print("__name__ =", __name__)
import b
print("__name__ =", __name__)
def f(): pass
print(f)
if __name__ == '__main__':
    print("f is b.a.f?", f is b.a.f)
import a
import a
import b
print("__name__ =", __name__)
print("a.f is b.a.f?", a.f is b.a.f)
运行
a.py
生成输出:

c = 0
我希望
b.py中
a.c=1
c
仍然是1

此外,我试图通过从
a.py
中删除
if uuuu name\uuuu=='\uuuu main\uuuu'
来进一步减少这种情况,但该示例不再运行:

Traceback (most recent call last):
  File "...\a.py", line 1, in <module>
    import b
  File "...\b.py", line 1, in <module>
    import a
  File "...\a.py", line 3, in <module>
    b.init()
AttributeError: module 'b' has no attribute 'init'
b.py

import a
def init():
    a.c = 1
print("__name__ =", __name__)
import b
print("__name__ =", __name__)
def f(): pass
print(f)
if __name__ == '__main__':
    print("f is b.a.f?", f is b.a.f)
import a
import a
import b
print("__name__ =", __name__)
print("a.f is b.a.f?", a.f is b.a.f)
c.py

import a
def init():
    a.c = 1
print("__name__ =", __name__)
import b
print("__name__ =", __name__)
def f(): pass
print(f)
if __name__ == '__main__':
    print("f is b.a.f?", f is b.a.f)
import a
import a
import b
print("__name__ =", __name__)
print("a.f is b.a.f?", a.f is b.a.f)
您可以通过运行
a.py
查看问题,并给出结果:

__name__ = __main__
__name__ = a
__name__ = a
<function f at 0x0000021A4A947840>
__name__ = __main__
<function f at 0x0000021A484E0400>
f is b.a.f? False

让我们一步一步地看一下您的两个模块示例。那里的行为是意料之中的,但一开始令人困惑,并且可能很好地解释了其他情况下的情况

如果将
a
作为脚本运行,则不会将其作为
a
导入
sys.modules
,而是作为
\uuuu main\uuu
导入。第一条语句是
import b
,它创建一个空的模块对象
sys.modules['b']
,并开始初始化它

b
的第一行再次导入
a
。通常,会在
sys.modules['a']
下找到一个模块对象,但在本例中,您是以脚本的形式运行
a
,因此初始导入是以不同的名称进行的。由于
a
的名称是
a
而不是
\uuuuu main\uuuuu
,因此
a.c
被设置为零,其他情况不发生

现在执行返回到
b
。它现在创建一个函数
init
,该函数将
sys.modules['a'].c
设置为一。我非常明确地写下了对
a
模块的引用,因为这是造成差异的根本原因

导入
b
后,执行返回到
a
,而不是
sys.modules['a']
。下一行,
c=0
实际上将
sys.modules['''uuuuu'main.'].c
设置为零。希望你现在能看到问题所在。下一行调用
b.init
,它将
sys.modules['a']
设置为一。然后打印
sys.modules[''\uuuuu main\uuuu']
,如预期的那样,它是零

要验证此说明的正确性,请尝试添加打印语句

print(sys.modules['a'].c)
您将获得
1
。另外,
sys.modules['a']是sys.modules[''''main']
将是
False
。解决这个问题的最简单方法是不要在给定模块的导入中初始化其他模块的成员

您的具体案例记录在此处:

其他资源


您可以在此处获得有关导入系统的详细信息:。这里介绍了各种进口陷阱和注意事项:。

这一点的可能重复看起来很相关:无论是什么样的修剪,都必须有一个线索,才能消除问题。同样奇怪的是,您的输出显示
event\u count
实际上没有增加。我敢打赌,如果您运行
eventcount(4)
,然后运行
eventcount(0)
,您将得到预期的结果。因此,错误必须出现在
e.setvalue()
Quote中:“e.setvalue()中的最后一个操作是调用eventcount(0)”。这有什么意义?