小能豆

在 python 中从模块导入变量会进行复制吗?

py

看起来这样做from foo import i会复制 i,而不是将 i 导入当前命名空间。这可能吗?

foo.py:

i=0

bar.py:

import foo
from foo import i

foo.i = 999

print i
print foo.i

这将打印:

0
999

但我希望它们都是 999(只是同一内存的别名)。我遗漏了什么?


阅读 21

收藏
2024-12-05

共1个答案

小能豆

在 Python 中,from foo import iimport foo 是两种不同的导入方式,它们的行为有所不同,这就是您观察到的现象。

解释:

  1. import foo:这会将 foo 模块导入到当前命名空间,并且通过 foo.i 可以访问 foo 模块中的 i。此时 foo 是一个模块对象,foo.i 是模块 foo 中的变量 i 的引用。

  2. from foo import i:这种导入方式会将 foo 模块中的 i 变量直接导入到当前命名空间中。这意味着变量 i 会被复制到当前的命名空间,而不是创建一个引用。因此,您实际上是复制了 foo.i 的值到 bar.py 中的一个新的变量 i

  3. from foo import i 之后,ifoo.i 是两个独立的变量。改变其中一个变量的值不会影响另一个。

为什么会看到不同的输出:

foo.i = 999
print(i)  # 输出 0
print(foo.i)  # 输出 999
  • foo.i = 999 直接修改了 foo 模块中的 i
  • print(i) 输出的是 0,因为 i 是从 foo 模块中导入的一个副本,导入时它的值是 0,而且它和 foo.i 没有关联。
  • print(foo.i) 输出的是 999,因为 foo.i 直接引用了 foo 模块中的 i,修改后它变成了 999

如何让它们指向同一内存地址?

要让 ifoo.i 共享同一个内存地址,您应该避免使用 from foo import i,而使用 import foo。这样,foo.ii 将始终引用同一个变量。

修改代码如下:

bar.py

import foo

foo.i = 999  # 修改 foo 中的 i
print(foo.i)  # 输出 999
print(foo.i)  # 输出 999

结论:

  • 如果你想让 ifoo.i 引用同一个变量,应该使用 import foo
  • 使用 from foo import i 会将 i 的值复制到当前命名空间中,它们将变成独立的变量。

希望这个解释能够解决您的问题!

2024-12-05