首页 > 解决方案 > 当您已经直接导入模块时,是否有使用完整方式模块的意义?

问题描述

在这种导入的情况下:

from app.settings import setting1

  1. settings.setting1
  2. setting1

是否存在需要在代码中使用选项 1,但选项 2 不起作用的情况?

标签: pythonimport

解决方案


from app.settings import setting1
settings.setting1  # error!

这是行不通的,因为settings它是一个无界的名称。在当前范围内,您只有定义了setting1print(locals())才能确认您。

所以我假设你的意思是:

import app.settings as settings
from app.settings import setting1
# difference between :
setting1
# and :
settings.setting1 = 43

两者之间存在细微差别。
通过这样做,您可以在名称和模块中的相应值from app.settings import setting1之间的当前范围内创建绑定。该值被复制。无论这是对可变对象还是不可变对象的引用,都会改变您查看对其所做更改的方式。 一个例子:setting1app.settings

# file: app/settings.py
setting1 = 80
# file: main.py
import app.settings as settings
from app.settings import setting1
print(f"after import, setting1: {setting1}")                      # 80

settings.setting1 = 43
print(f"after assign n°1, module setting1: {settings.setting1}")  # 43
print(f"after assign n°1, local setting1: {setting1}")            # 80

setting1 = -11
print(f"after assign n°2, module setting1: {settings.setting1}")  # 43
print(f"after assign n°2, local setting1: {setting1}")            # -11

导入复制了值80并将其绑定到setting1当前范围内的名称,而另一个值80存在于模块中。它们是不同的(因为不可变),因此更改一个不会影响另一个。

但是,如果我使用可变对象(例如列表),这就是我得到的:

# file: app/settings.py
setting1 = [80]
# file: main.py
import app.settings as settings
from app.settings import setting1
print(f"after import, setting1: {setting1}")                      # [80]

settings.setting1.append(43)
print(f"after append n°1, module setting1: {settings.setting1}")  # [80, 43]
print(f"after append n°1, local setting1: {setting1}")            # [80, 43]

setting1.append(-11)
print(f"after append n°2, module setting1: {settings.setting1}")  # [80, 43, -11]
print(f"after append n°2, local setting1: {setting1}")            # [80, 43, -11]

在这里,使用本地绑定或来自模块的引用没有任何改变,它们都只是对同一个可变对象的引用。

我曾经遇到过这样的问题:我导入了在 mudule 顶层定义的变量以共享数据,但是当导入时from my.module import my_shared_variable(默默地)创建了一个副本,并且实际上没有共享数据。所以我不得不使用第一个选项,因为第二个选项没有做我想要的。

除了这个可变/不可变的陷阱之外,如果你没有对你的导入做一些棘手的事情,那么两者都是等价的。


推荐阅读