我试图让我的程序内存占用受到控制。我以为我从导入开始,因为我只使用相当大的PyObjC
库中的3-4个函数。但是,我有点惊讶地发现,导入较大模块的特定部分与实际加载到内存中的内容无关。
在OSX上加载整个Quartz.CoreGraphics库:
Line # Mem usage Increment Line Contents
================================================
77 @profile
78 7.953 MB 0.000 MB def test_import_all():
79 26.734 MB 18.781 MB import Quartz.CoreGraphics as CG
它以几乎19MB的速度拉入整个库。
尝试只提取我需要的内容会产生相同的19MB结果:
Line # Mem usage Increment Line Contents
================================================
82 @profile
83 7.941 MB 0.000 MB def test_import_some():
84 26.727 MB 18.785 MB from Quartz.CoreGraphics import CGImageGetWidth
因此,似乎特定的导入与实际加载的内容无关。
只需要一小部分来自其他巨大模块的功能,这似乎是一个常见的用例。有没有办法将仅从模块加载到内存中,或者这只是使用外部库的结果?
答案 0 :(得分:5)
这就是模块加载的工作原理。运行时维护一组已加载的模块,因此即使您只导入了几个符号,也可以访问整个模块。这有两个可取的后果:
如果您认为模块中的任何函数都可以直接使用其中的名称或通过globals()
,sys.modules[__name__]
,eval
间接访问模块名称空间,那么这也是不可避免的,管他呢。因此,除非进行一些聪明的优化以证明特定函数不执行此操作(Python实现通常不会烦恼),整个模块命名空间必须在内存中。
答案 1 :(得分:0)
不,没有,因为即使您认为只需要一个函数,该函数也可能需要模块中的其他函数(或类等)。模块是可以通过导入加载的最小代码单元。如果模块可以分成多个独立的部分,并且它足够大,这会对性能产生影响,那么它应该是。否则,您不能仅导入部分和/或如果可以的话无关紧要。