如何从另一个模块更改模块变量?

2020/12/01 01:31 · python ·  · 0评论

假设我有一个名为的软件包bar,其中包含bar.py

a = None

def foobar():
    print a

__init__.py

from bar import a, foobar

然后我执行以下脚本:

import bar

print bar.a
bar.a = 1
print bar.a
bar.foobar()

这是我的期望:

None
1
1

这是我得到的:

None
1
None

谁能解释我的误解?

您正在使用from bar import aa在导入模块的全局范围(或​​发生import语句的任何范围)中成为符号。

当您为指定新值时a,您也只是在更改哪些值a点,而不是实际值。尝试bar.py直接使用import barin导入__init__.py并通过设置那里进行实验bar.a = 1这样,您实际上将在此上下文中修改bar.__dict__['a']哪个是“实际”值a

它有点令人费解,分为三层,但bar.a = 1更改了实际上源自的a名为模块的值它不会更改看到因为它存在于实际文件中您可以设置是否要更改它。bar__init__.pyafoobarfoobarbar.pybar.bar.a

这是使用语句from foo import bar形式的危险之一import:它将分成bar两个符号,一个符号在全局范围内可见,从foo符号开始指向原始值,而另一个符号在import执行语句的范围内可见更改符号指向的位置也不会更改其指向的值。

尝试reload从交互式解释器访问模块时,这种东西是致命的

这个问题困难的一个原因是,你有一个名为程序bar/bar.pyimport bar可导入bar/__init__.pybar/bar.py,取决于它完成,这使得它有点笨重跟踪哪些abar.a

下面是它的工作原理:

了解发生了什么,关键是要认识到,在你的__init__.py

from bar import a

实际上做了类似的事情

a = bar.a
# … where bar = bar/bar.py (as if bar were imported locally from __init__.py)

并定义一个新变量(bar/__init__.py:a,如果需要的话)。因此,您的from bar import ain__init__.py会将名称绑定bar/__init__.py:a到原始bar.py:a对象(None)。这就是为什么你可以做from bar import a as a2__init__.py:在这种情况下,很显然,你有两个bar/bar.py:a和一个不同的变量名bar/__init__.py:a2(在你的情况下,这两个变量的名字恰好两者a,但他们仍然生活在不同的命名空间:在__init__.py,它们是bar.aa)。

现在,当你做

import bar

print bar.a

您正在访问变量bar/__init__.py:a(因为import bar导入了your bar/__init__.py)。这是您修改的变量(为1)。您没有触及variable的内容bar/bar.py:a所以当你随后做

bar.foobar()

您调用bar/bar.py:foobar(),它会访问afrom的变量bar/bar.py,后者仍然是Nonefoobar()定义后,它将一劳永逸地绑定变量名称,因此ainbar.pybar.py:a,而不是a另一个模块中定义的任何其他变量-因为a在所有导入的模块中可能有很多变量)。因此是最后一个None输出。

结论:最好是避免任何含糊之处import bar,由具有任何bar/bar.py模块(因为bar.__init__.py品牌目录bar/包已经,您还可以导入import bar)。

换一种说法:事实证明,这种误解很容易造成。
它在Python语言参考中被偷偷地定义:使用object代替symbol我建议使用Python语言参考使这一点更清晰,更稀疏。

from形式不结合模块名称:它通过标识符的列表,看起来它们中的每一个向上的模块中,在步骤(1)中发现,并结合在本地名称空间中的名称对象从而找到。

然而:

导入时,您将导入已导入符号的当前值,并将其添加到已定义的命名空间中。 您不是在导入参考,而是在有效导入值。

因此,要获取的更新值i,必须导入一个变量,该变量包含对该符号的引用。

换句话说,导入import与JAVA中的,externalC / C ++中的声明甚use至PERL中子句都不一样

而是在Python中执行以下语句:

from some_other_module import a as x

是更喜欢在K&R C下面的代码:

extern int a; /* import from the EXTERN file */

int x = a;

(注意:在Python情况下,“ a”和“ x”本质上是对实际值的引用:您不是在复制INT,而是在复制引用地址)

本文地址:http://python.askforanswer.com/ruheconglingyigemokuaigenggaimokuaibianliang.html
文章标签: ,   ,  
版权声明:本文为原创文章,版权归 admin 所有,欢迎分享本文,转载请保留出处!

文件下载

老薛主机终身7折优惠码boke112

上一篇:
下一篇:

评论已关闭!