Python3.10.6

假设您有以下文件:

main.py
setter.py
Folder/shared.py

这些内容包括:

# Folder/shared.py
class Shared:
    i = 0 # something that is used in multiple locations
# setter.py
from Folder.shared import Shared
def set_i():
    global Shared
    print("mem in setter: " + hex(id(Shared.i)))
    Shared.i = 2 # set the shared resource
# main.py
IMPORT_VIA_PATH = False
if IMPORT_VIA_PATH:
    import sys, os
    pwd = os.path.dirname(os.path.abspath(__file__))
    shared_path = pwd + '/Folder'
    sys.path.insert(0, shared_path)
    from shared import Shared
else:
    from Folder.shared import Shared
from setter import set_i
set_i()
print(Shared.i)
print("mem in main: " + hex(id(Shared.i)))

If IMPORT_VIA_PATH is False, main prints 2 for i's value, and the memory addresses are different.
If IMPORT_VIA_PATH is True, main prints 0 for i's value, and the memory addresses are the same.


更令人困惑的是,如果在整个过程中,只有i人取代了Shared.i人:

# Folder/shared.py
i = 0 # something that is used in multiple locations
# setter.py
from Folder.shared import i
def set_i():
    global i
    print("mem in setter: " + hex(id(i)))
    i = 2 # set the shared resource
# main.py
IMPORT_VIA_PATH = True
if IMPORT_VIA_PATH:
    import sys, os
    pwd = os.path.dirname(os.path.abspath(__file__))
    shared_path = pwd + '/Folder'
    sys.path.insert(0, shared_path)
    from shared import i
else:
    from Folder.shared import i
from setter import set_i
set_i()
print(i)
print("mem in main: " + hex(id(i)))

则对于IMPORT_VIA_PATHTrueFalse两者,i保持零,并且存储器地址是the same.这里发生什么事情?

推荐答案

因为如果从不同的路径导入,即导入语句使用不同的模块名称,则Python会将其视为as a different module.在一种情况下,sys.modules将包含"Folder.shared",因此当您导入shared时,它将判断"shared"是否在sys.modules中,而不是找到它,因此它不仅检索已经导入的模块,然后将其作为新模块导入.

几乎有certainly个人从一开始就没有充分的理由这样做.所以你不应该这么做.

在Python中没有"原语".然而,CPythonhas an implementation detailsmall integers are cached,这就是为什么相同的对象被重复用于整数0.

此外,当您 Select from module import i时,您会将值module.i赋给导入模块中的一个新变量.

所以of course i是不变的.它是一个不同的变量(可能引用相同的对象)

拨打set_i只会影响module.i,而不会影响main模块中的i.

Python相关问答推荐

如何让 turtle 通过点击和拖动来绘制?

如何计算两极打印机中 * 所有列 * 的出现次数?

标题:如何在Python中使用嵌套饼图可视化分层数据?

在Pandas DataFrame操作中用链接替换'方法的更有效方法

运行终端命令时出现问题:pip start anonymous"

大小为M的第N位_计数(或人口计数)的公式

如何从在虚拟Python环境中运行的脚本中运行需要宿主Python环境的Shell脚本?

PyQt5,如何使每个对象的 colored颜色 不同?'

递归访问嵌套字典中的元素值

为一个组的每个子组绘制,

计算分布的标准差

使用Python和文件进行模糊输出

为什么numpy. vectorize调用vectorized函数的次数比vector中的元素要多?

Python Tkinter为特定样式调整所有ttkbootstrap或ttk Button填充的大小,适用于所有主题

python sklearn ValueError:使用序列设置数组元素

使用Openpyxl从Excel中的折线图更改图表样式

在极点中读取、扫描和接收有什么不同?

Pandas在rame中在组内洗牌行,保持相对组的顺序不变,

你能把函数的返回类型用作其他地方的类型吗?'

删除Dataframe中的第一个空白行并重新索引列