Python是否引用了my'中的同一个实例;从Bla导入Bla';陈述

Python是否引用了my'中的同一个实例;从Bla导入Bla';陈述,python,python-import,python-module,Python,Python Import,Python Module,假设我有以下伪代码。在两个文件中导入bla是指bla的两个实例,还是指同一个实例?换句话说,我可以在Python中这样的不同文件中连接和断开单个连接吗 bla.py import socket class Bla: connect(self): self.connection = socket.socket(...) disconnect(self): self.connection.close() bla = Bla() from bla import bla bla

假设我有以下伪代码。在两个文件中导入
bla
是指
bla
的两个实例,还是指同一个实例?换句话说,我可以在Python中这样的不同文件中连接和断开单个连接吗

bla.py

import socket
class Bla:
  connect(self):
    self.connection = socket.socket(...)
  disconnect(self):
    self.connection.close()
bla = Bla()
from bla import bla
bla.connect()
from bla import bla
bla.disconnect()
你好.py

import socket
class Bla:
  connect(self):
    self.connection = socket.socket(...)
  disconnect(self):
    self.connection.close()
bla = Bla()
from bla import bla
bla.connect()
from bla import bla
bla.disconnect()
world.py

import socket
class Bla:
  connect(self):
    self.connection = socket.socket(...)
  disconnect(self):
    self.connection.close()
bla = Bla()
from bla import bla
bla.connect()
from bla import bla
bla.disconnect()

是的,在
hello
world
中,
bla
引用相同的实例

模块是单例的,它们的名称空间只有一个副本。第一次导入模块时,顶级语句(函数和生成器之外的所有语句)只执行一次

模块在中进行管理。首先导入可确保模块已加载并显示在
sys.modules
中,然后在导入命名空间中绑定名称。基本上,
from bla import bla
执行与
bla=sys.modules['bla'].bla
赋值语句相同的操作。因此,将模块加载到内存只需一次,您的
bla=bla()
只需执行一次,所有进一步的导入都将访问该实例的引用

从:

基本导入语句(no
from
子句)分两步执行:

  • 找到一个模块,加载并在必要时初始化它
  • 在本地命名空间中为出现
    import
    语句的作用域定义一个或多个名称
  • [……]

    来自表单的
    使用了稍微复杂一些的过程:

  • 找到from子句中指定的模块,加载并在必要时初始化它
  • 对于
    导入
    条款中指定的每个标识符:
  • 检查导入的模块是否具有该名称的属性
  • 如果没有,请尝试导入具有该名称的子模块,然后再次检查导入的模块是否具有该属性
  • 如果未找到该属性,将引发
    ImportError
  • 否则,对该值的引用将存储在本地命名空间中,如果存在,则使用
    as
    子句中的名称,否则使用属性名称

  • (我的粗体强调)。

    是的,在
    hello
    world
    中,
    bla
    引用了相同的实例

    模块是单例的,它们的名称空间只有一个副本。第一次导入模块时,顶级语句(函数和生成器之外的所有语句)只执行一次

    模块在中进行管理。首先导入可确保模块已加载并显示在
    sys.modules
    中,然后在导入命名空间中绑定名称。基本上,
    from bla import bla
    执行与
    bla=sys.modules['bla'].bla
    赋值语句相同的操作。因此,将模块加载到内存只需一次,您的
    bla=bla()
    只需执行一次,所有进一步的导入都将访问该实例的引用

    从:

    基本导入语句(no
    from
    子句)分两步执行:

  • 找到一个模块,加载并在必要时初始化它
  • 在本地命名空间中为出现
    import
    语句的作用域定义一个或多个名称
  • [……]

    来自
    表单的
    使用了稍微复杂一些的过程:

  • 找到from子句中指定的模块,加载并在必要时初始化它
  • 对于
    导入
    条款中指定的每个标识符:
  • 检查导入的模块是否具有该名称的属性
  • 如果没有,请尝试导入具有该名称的子模块,然后再次检查导入的模块是否具有该属性
  • 如果未找到该属性,将引发
    ImportError
  • 否则,对该值的引用将存储在本地命名空间中,如果存在,则使用
    as
    子句中的名称,否则使用属性名称

  • (粗体强调)。

    这将是来自bla导入bla的
    ,小写。您的模块文件是
    bla.py
    ,而不是
    bla.py
    。这将是来自bla import bla
    ,小写。您的模块文件是
    bla.py
    ,而不是
    bla.py
    。需要注意的是:如果您从两个不同的限定路径导入相同的模块,您可能会得到两个不同的模块实例,每个实例都有自己不同的
    bla
    对象。@brunodesthuilliers:您必须为模块使用不同的名称,
    sys.modules
    命名空间不支持重复。如果将
    bla.py
    用作主脚本,并且在某个地方有一个
    import bla
    语句,则仍然会发生这种情况,然后您会得到
    sys.modules[''''''''''''''.[code>和
    sys.modules['bla']
    。我在django项目中也看到过这种情况,其中项目根本身就是一个包,因此,如果在
    sys.path
    中同时有项目根目录的父路径和项目根目录路径,并且有一个从项目根目录(
    从myproject.someapp导入某些内容
    ),另一个没有项目根目录(
    从someapp导入某些内容
    )您将得到两个不同的模块-这就是我所说的“不同的限定路径”(我假设您所说的“不同的名称”是什么意思)。需要注意的是:如果您从两个不同的限定路径导入同一个模块,您可能会得到两个不同的模块实例,每个实例都有自己的不同的
    bla
    对象。@Brunodesshuilliers:您必须为模块使用不同的名称,
    sys.modules
    命名空间不支持重复的名称。
    sys.modules
    命名空间不支持重复