python中的导入是静态的,任何解决方案?

时间:2009-04-13 15:52:59

标签: python

foo.py:

i = 10

def fi():
    global i
    i = 99

bar.py:

import foo
from foo import i

print i, foo.i
foo.fi()
print i, foo.i

这是有问题的。为什么ifoo.i更改时不会发生变化?

4 个答案:

答案 0 :(得分:8)

罗斯所说的是如此重建foo:

_i = 10

def getI():
    return _i

def fi():
    global _i
    _i = 99

然后你会看到它按你想要的方式工作:

>>> import foo
>>> print foo.getI()
10
>>> foo.fi()
>>> print foo.getI()
99

从某种意义上说,它也是“更好”,你可以避免导出全局,但仍然提供对它的读访问权。

答案 1 :(得分:7)

import bar.pyi模块命名空间中设置了一个名为bar.py的标识符,该标识符指向与{{1}标识符相同的地址在i模块命名空间中。

这是一个重要的区别...... foo.py并未指向bar.i,而是指向对象foo.i所在的内存中的同一空间10碰巧指的是同一时间。在python中,变量名不是内存空间......它们是指向内存空间的标识符。在bar中导入时,您将设置本地名称空间标识符。

当foo.py命名空间中的标识符foo.i更改为指向文字99时,您的代码在调用foo.fi()之前的行为与预期一致,文本99在内存中显然是一个不同的对象现在,i的模块级命名空间字典foo标识了内存中的不同对象,而不是bar.py中的标识符i

Shane和rossfabricant对如何调整模块以达到你想要的效果提出了很好的建议。

答案 2 :(得分:3)

i内的foo.pyi中的不同 bar.py。当你在bar.py时:

from foo import i

这会在i中创建一个新的bar.py引用与i中的foo.py相同的对象

您的问题是:当您拨打foo.fi()并执行此操作时:

i = 99

该分配使foo.py的{​​{1}}指向另一个整数对象(i)。整数对象本身是不可变的(谢天谢地),所以它只会改变99的{​​{1}}指向的内容。不是foo.py的{​​{1}}。 i的{​​{1}}仍指向之前指向的旧对象。 (整数不可变对象bar.py

您可以通过在i中放置以下命令来测试我在说什么:

bar.py

它应该打印i

答案 3 :(得分:0)

您可以调用函数而不是引用全局变量。