【问题标题】:Python - Confusion about importing same module by two other moduesPython - 关于由其他两个模块导入相同模块的困惑
【发布时间】:2017-04-09 18:22:40
【问题描述】:

我在尝试使用pymodm 创建flask-extension 时注意到了这一点。 考虑pymodm.MongoModel 的用例。

Models.py(用户定义的模块)

#line 1
from pymodm import MongoModel, fields,connect

#line 2
connect("mongodb://localhost:27017/project_matrix")

#line 3
class Model(MongoModel):
    name = fields.CharField()

#line 4
Model({"name": "test"}).save()

connections.py 模块的connect 方法的有趣之处在于,它使用一个名为_CONNECTIONS 的模块级变量来存储所有连接。 导入连接到#line 2 中的当前名称空间后,我们正在使用连接方法添加到_CONNECTIONS 的连接。

然后,在#line 4中,调用models.py模块的TopLevelMongoModel类的save方法,间接调用options.pycollections()options.py 导入 connections.py 的方法 _get_db

夏天:

Models.py 导入connections.py 的连接方法以添加到模块级变量的连接。 options.py 导入 connections.py 的 _get_db 以某种方式设法从 _CONNECTIONS 获得连接,该连接由 Models.py 更改。

这背后的机制/概念是什么?模块级变量是像JavaScript 中的全局变量还是我遗漏了什么?

【问题讨论】:

  • 我不确定你在问什么。只有一个 _CONNECTIONS 实例被其他两个模块使用;为什么这令人惊讶?
  • 好吧..如果一个模块由两个模块导入,这两个模块应该有两个_CONNECTIONS实例而不是一个..
  • 但是为什么呢?什么让你有那个想法?如果您将一个对象分配给两个名称,您仍然只有一个对象,而不是两个。
  • 是根本问题:Flask 为什么/如何遵循在应用级别设置扩展配置的约定?

标签: python mongodb python-import pymodm


【解决方案1】:

如果一个模块由两个模块导入,那么这两个模块应该有两个 _CONNECTIONS 实例而不是一个。

事实并非如此。

您的导入以这种方式工作,因为这就是导入的工作方式。 import 语句不会在每次调用时创建新模块。如果该模块之前已导入,则后续导入只需绑定到原始模块。

考虑这三个文件:

main.py

import a
import b
print(f"main, imports complete, a.x={a.x}, b.a.x={b.a.x}")
a.x = 7
print(f"modified a.x, a.x={a.x}, b.a.x={b.a.x}")

a.py

x = 3
print(f"Inside a, x={x}")

b.py

import a
print(f"Inside b, a.x={a.x}")

还有这个 python3.6 会话:

$ python3.6 main.py
Inside a, x=3
Inside b, a.x=3
main, imports complete, a.x=3, b.a.x=3
modified a.x, a.x=7, b.a.x=7

注意两件重要的事情:

  • Inside a 行只打印一次。即使a 是从mainb 导入的,Inside a 也只会在第一次导入a 时打印。这很重要:a 中的代码只执行一次。

  • a.x 的修改同时影响a.xb.a.x。这也很重要。只有一个a 模块,因此只有一个a 模块命名空间。导入a 的任何人都会看到具有相同名称和相同对象的相同命名空间。

【讨论】:

    猜你喜欢
    • 2014-11-30
    • 1970-01-01
    • 1970-01-01
    • 2018-09-11
    • 2010-11-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-05
    相关资源
    最近更新 更多