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()
只需执行一次,所有进一步的导入都将访问该实例的引用
从:
基本导入语句(nofrom
子句)分两步执行:
import
语句的作用域定义一个或多个名称使用了稍微复杂一些的过程:
找到from子句中指定的模块,加载并在必要时初始化它强>
对于导入
条款中指定的每个标识符:
检查导入的模块是否具有该名称的属性
如果没有,请尝试导入具有该名称的子模块,然后再次检查导入的模块是否具有该属性
如果未找到该属性,将引发ImportError
否则,对该值的引用将存储在本地命名空间中,如果存在,则使用as
子句中的名称,否则使用属性名称
(我的粗体强调)。是的,在hello
和world
中,bla
引用了相同的实例
模块是单例的,它们的名称空间只有一个副本。第一次导入模块时,顶级语句(函数和生成器之外的所有语句)只执行一次
模块在中进行管理。首先导入可确保模块已加载并显示在sys.modules
中,然后在导入命名空间中绑定名称。基本上,from bla import bla
执行与bla=sys.modules['bla'].bla
赋值语句相同的操作。因此,将模块加载到内存只需一次,您的bla=bla()
只需执行一次,所有进一步的导入都将访问该实例的引用
从:
基本导入语句(nofrom
子句)分两步执行:
找到一个模块,加载并在必要时初始化它
在本地命名空间中为出现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
命名空间不支持重复