Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/15.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 - Fatal编程技术网

Python 从另一个模块引用的变量值在其自身模块中更改后不会更改

Python 从另一个模块引用的变量值在其自身模块中更改后不会更改,python,Python,我开始写python程序有一段时间了,但我不是很擅长,目前我遇到了一个问题,看起来很奇怪,至少对我来说是这样 假设我们有两个源文件,称为A.py和B.py,其内容如下: A.py B.py 然后我运行了python A.py,输出如下: global: not set yet class var: not set yet ============================ global(in B): not set yet class var(in B)

我开始写python程序有一段时间了,但我不是很擅长,目前我遇到了一个问题,看起来很奇怪,至少对我来说是这样

假设我们有两个源文件,称为A.py和B.py,其内容如下:

A.py

B.py

然后我运行了python A.py,输出如下:

global:          not set yet
class var:       not set yet
============================
global(in B):    not set yet
class var(in B): not set yet
============================
global(in A):    value set for global
class var(in A): value set for class var
在我看来,前4个输出应该与后2个输出一致,但事实并非如此,似乎该值是在类和方法定义期间设置的,不能更改。它与许多其他语言(如Java)非常不同。那么,有谁能帮我解释一下,或者给我贴一些链接来帮助我理解它吗?有什么解决办法吗

提前感谢,

开尔文

================编辑==============

谢谢@icktoofay、@hop和@RocketDonkey,在我尝试了下面的代码之后,我确实找到了根本原因:

import sys
import A
import __main__

__global__ = 'not set yet'

class Data:
    __var__ = 'not set yet'

def init():
    global __global__
    __global__ = 'value set for global'
    Data.__var__ = 'value set for class var'

if __name__ == '__main__':
    init()

    for key in sys.modules.keys():
        if key in ['__main__', 'A']:
            print key + ' : ' + sys.modules[key].__file__
    print '===================='
    print 'A: ' + A.__global__
    print 'A: ' + A.Data.__var__
    print '===================='
    print __main__.__global__
    print __main__.Data.__var__
输出为:

__main__ : A.py
A : D:\test\python\A.py
====================
A: not set yet
A: not set yet
====================
value set for global
value set for class var
这是因为文件A.py被导入了两次,一个名为_umain _uu,另一个名为A,在模块_umain uuu中更改了值,但对于模块B,该值是从模块A获得的,因此该值没有更改

我确实需要深入了解python的模块导入:-D

循环导入A导入B,B导入A与作为主脚本的一个模块的组合是问题所在

Python如何导入模块 当您要求Python导入模块时,它首先查看sys.modules以查看是否已经存在同名模块。如果是这样,它只使用该模块。如果没有该名称的模块,它将生成一个新的模块对象,将其放置在sys.modules中,并在该模块中运行相应的Python代码

主要剧本 Python脚本中使用了一个流行的成语:无处不在

if __name__ == '__main__':
当Python想要运行主脚本时,它会导入名为uuu main_uuu的模块

当您的主脚本只处理其他模块时,这很好,但是当其他模块想要再次处理主模块时,您会遇到麻烦:再次导入主模块的脚本很可能是使用一个普通名称导入它,如本例中的a。不幸的是,已加载的模块没有命名为a;它的名字叫uuu main

解决 一个非常简单的解决方案就是删除其他模块对主模块的依赖关系。这样,您就不会遇到这种不直观的行为。一种方法是让主脚本只是一个存根,调用另一个模块的主函数或其他东西

另一种解决方案是让主脚本手动改变sys.modules,以另一个名称命名。这有点老套,但很管用:

sys.modules['A'] = sys.modules[__name__]
现在您知道了。

循环导入A导入B,B导入A与作为主脚本的模块之一相结合是问题所在

Python如何导入模块 当您要求Python导入模块时,它首先查看sys.modules以查看是否已经存在同名模块。如果是这样,它只使用该模块。如果没有该名称的模块,它将生成一个新的模块对象,将其放置在sys.modules中,并在该模块中运行相应的Python代码

主要剧本 Python脚本中使用了一个流行的成语:无处不在

if __name__ == '__main__':
当Python想要运行主脚本时,它会导入名为uuu main_uuu的模块

当您的主脚本只处理其他模块时,这很好,但是当其他模块想要再次处理主模块时,您会遇到麻烦:再次导入主模块的脚本很可能是使用一个普通名称导入它,如本例中的a。不幸的是,已加载的模块没有命名为a;它的名字叫uuu main

解决 一个非常简单的解决方案就是删除其他模块对主模块的依赖关系。这样,您就不会遇到这种不直观的行为。一种方法是让主脚本只是一个存根,调用另一个模块的主函数或其他东西

另一种解决方案是让主脚本手动改变sys.modules,以另一个名称命名。这有点老套,但很管用:

sys.modules['A'] = sys.modules[__name__]

现在你知道了。

+1到@icktoofay-我会比我的答案更看重这个答案,所以对这一点持保留态度,因为这是我公认的对这个过程缺乏经验的理解:

正如其他人提到的,你们的主要问题是循环进口。其他人会更明智地评论,但现在发生的事情的要点是:

import B—这会在运行A.py`后立即发生,因此您可以转到B.py并立即遇到import A。 由于A在当前名称空间中具有不同的名称,因此会再次导入它以验证这一点,请在A.py中的导入B上方添加print _____; name _____;-您将看到两个不同的名称出现。 当A被导入到B中时,它带来了_global__='notseen yet'声明,所以 n您说self.glo=A.uuuu global_uuuuuu,您得到的是该变量,而不是修改后的变量,因为该特定代码不会在该版本的A中执行。 与A.Data相同。_var__-您尚未在此模块中运行init,因为它不是您的“主”A,因此尚未修改任何内容。 根据以上内容,您可以看到为什么A._全局__和A.Data._var__还会显示“尚未看到”-它们尚未修改,并且与上面的变量相同。 在_main____________________________________________。
+1至@icktoofay-我会比我的答案更看重这个答案,所以请恕我直言,因为这是我公认的对这个过程缺乏经验的理解:

正如其他人提到的,你们的主要问题是循环进口。其他人会更明智地评论,但现在发生的事情的要点是:

import B—这会在运行A.py`后立即发生,因此您可以转到B.py并立即遇到import A。 由于A在当前名称空间中具有不同的名称,因此会再次导入它以验证这一点,请在A.py中的导入B上方添加print _____; name _____;-您将看到两个不同的名称出现。 当A被导入到B中时,它带来了uuu global_uuuu='not seen yet'声明,因此当你说self.glo=A.uu global_uuu时,你得到的是那个变量,而不是修改过的变量,因为这个特定的代码没有在这个版本的A中执行。 与A.Data相同。_var__-您尚未在此模块中运行init,因为它不是您的“主”A,因此尚未修改任何内容。 根据以上内容,您可以看到为什么A._全局__和A.Data._var__还会显示“尚未看到”-它们尚未修改,并且与上面的变量相同。 在_main____________________________________________。
不要使用循环imports@hop是的,我知道这不是一个好的编程习惯,但目前我只想知道“为什么”,我将修改我的代码并删除循环导入。您的strsys.modules[key]可能可以调试,但最好只使用sys.modules[key]。__文件。@icktoofay是的,我使用str只是为了测试,我已经按照你的建议更新了代码,谢谢。不要使用循环imports@hop是的,我知道这不是一个好的编程习惯,但目前我只想知道“为什么”,我将修改我的代码并删除循环导入。您的strsys.modules[key]可能可以调试,但是使用sys.modules[key]要好得多。__文件_。@icktoofay是的,我使用str只是为了测试,我已经按照你的建议更新了代码,谢谢。@icktoofay谢谢你的回答,刚才我用一些代码进行了测试,并找到了根本原因,我会在我的问题之后粘贴代码。@icktoofay:是的,我们在谈论同一件事。这就是为什么我不想再麻烦了别这么做!我删除了我的东西以避免混淆。@icktoofay谢谢你的回答,刚才我用一些代码进行了测试,并找到了根本原因,我将在我的问题后粘贴我的代码。@icktoofay:是的,我们讨论的是同一件事。这就是为什么我不想再麻烦了别这么做!我删除了我的资料,以免增加混乱。是的,谢谢你的回答,我刚才确实找到了根本原因-谢谢你的回答,我刚才确实找到了根本原因-D