为了提高效率,我试图弄清楚python是如何使用它的对象堆(和命名空间系统,但它或多或少是清晰的)的。因此,基本上,我试图了解对象何时加载到堆中,其中有多少对象,它们的寿命有多长等。
我的问题是,当我使用一个包并从中导入一些东西时,我的问题是。
from pypackage import pymodule
将哪些对象加载到内存( python解释器的对象堆)中?更普遍的是:发生了什么?:)
我猜想上面的例子是这样的:在内存中创建了包pypackage
的一些对象(它包含了一些关于包的信息,但不是太多),模块pymodule
被加载到内存中,它的引用是在本地名称空间中创建的。这里很重要的一点是:内存中没有创建pypackage
的其他模块(或其他对象),除非明确说明(在模块本身中,或者在包初始化技巧和钩子中的某个地方,我不熟悉)。最后,内存中唯一重要的东西是pymodule
(即导入模块时创建的所有对象)。是这样吗?如果有人能稍微澄清一下这个问题,我将不胜感激。也许你可以建议一些关于它的有用文章?(文档涵盖了更多特定内容)
我发现了以下关于模块导入的相同问题:
当Python导入一个模块时,它首先检查模块注册表(sys.modules),看看该模块是否已经导入。如果是这种情况,Python将按原样使用现有的模块对象。
否则,Python会执行如下操作:
创建一个新的空模块对象(这本质上是一个编译模块代码对象的dictionary)
如果您能为我们提供关于套餐的同样的解释,我将不胜感激。
顺便说一句,使用包时,模块名称会奇怪地添加到sys.modules
中:
>>> import sys
>>> from pypacket import pymodule
>>> "pymodule" in sys.modules.keys()
False
>>> "pypacket" in sys.modules.keys()
True
还有一个关于同一问题的实际问题。
当我构建一组工具时,这些工具可能会在不同的过程和程序中使用。我把它们放在模块里。我别无选择,只能加载一个完整的模块,即使我只想使用其中声明的一个函数。正如我所看到的,可以通过制作小模块并将它们放入包中(如果包在您只导入其中一个模块时没有加载所有模块)来减少这个问题的痛苦。
有没有更好的方法用Python制作这样的库?(只有函数,它们的模块中没有任何依赖项。)是否可以使用C-extensions?
另外,很抱歉问了这么长的问题。
发布于 2013-03-08 03:47:17
这里有几个不同的问题。。。
关于导入包
导入包时,步骤顺序与导入模块时相同。唯一的区别是包的代码(即创建“模块代码对象”的代码)是包的__init__.py
的代码。
因此,除非__init__.py
显式地加载,否则包的子模块不会被加载。如果使用from package import module
,则只加载module
,当然,除非它从包中导入其他模块。
从包中加载的模块的sys.modules
名称
当您从一个包中导入一个模块时,名称是,被添加到sys.modules
是指定模块名称的“限定名称”,以及您从中导入它的任何包的以点分隔的名称。所以如果你使用from package.subpackage import mod
,那么添加到sys.modules
中的就是"package.subpackage.mod"
。
仅导入模块的一部分
导入整个模块而不是只导入一个函数通常不是什么大问题。你说它是“痛苦的”,但实际上它几乎从来不是。
正如您所说,如果函数没有外部依赖关系,那么它们就是纯Python,加载它们不会花费太多时间。通常,如果导入一个模块需要很长时间,这是因为它加载了其他模块,这意味着它确实有外部依赖项,您必须加载整个模块。
如果您的模块具有在模块导入时发生的昂贵操作(即,它们是全局模块级代码,而不是在函数中),但对于使用模块中的所有函数来说并不是必需的,那么如果您愿意,可以重新设计您的模块,以将加载推迟到以后。也就是说,如果您的模块执行以下操作:
def simpleFunction():
pass
# open files, read huge amounts of data, do slow stuff here
您可以将其更改为
def simpleFunction():
pass
def loadData():
# open files, read huge amounts of data, do slow stuff here
然后告诉人们“当你想加载数据时调用someModule.loadData()
”。或者,如您所建议的,您可以将模块的昂贵部分放入包中各自独立的模块中。
我从来没有发现导入模块会导致有意义的性能影响,除非模块已经足够大,可以合理地将其拆分成更小的模块。制作大量的小模块,每个模块都包含一个函数,这不太可能给你带来任何好处,除了必须跟踪所有这些文件带来的维护麻烦。你是否真的有一个特定的情况,这会对你产生影响?
此外,关于您的最后一点,据我所知,全有或全无加载策略适用于C扩展模块和纯Python模块。显然,就像使用Python模块一样,您可以将其拆分成较小的扩展模块,但是如果不运行打包为扩展模块一部分的其余代码,则无法执行from someExtensionModule import someFunction
。
https://stackoverflow.com/questions/15280157
复制相似问题