如果从一个函数中导入模块 x 次,会有什么问题吗?
Are there any issues if importing modules x times from a function?
我提取 PyPDF2 1.26.0 工具包并将其放入我的插件目录中。层次结构如下所示:
plugin
|__example.py
|__report
|__PyPDF2
|__(PyPDF2 contents)
在 example.py
文件的开头,我尝试使用以下方法导入 PyPDF2 模块:
from report.PyPDF2.PyPDF2 import PdfFileMerger
不幸的是,这会导致错误:
ImportError: No module named report.PyPDF2.PyPDF2
但我可以使用 sys
:
导入它
import os, sys
class plugin:
def __init__(self, iface):
self.iface = iface
self.plugin_dir = os.path.dirname(__file__)
...
def pdf_merger(self):
# Import PyPDF2
sys.path.append(str(self.plugin_dir) + '/report/PyPDF2')
from PyPDF2 import PdfFileMerger
merger = PdfFileMerger()
return merger
def func(self):
merger = self.pdf_merger()
...
问题是 func()
会被调用多次,所以每次 from PyPDF2 import PdfFileMerger
都会被调用 运行。这会导致任何问题(即内存问题等)吗?为什么我不能使用 from report.PyPDF2.PyPDF2 import PdfFileMerger
导入模块?
你试过了吗:
from report.PyPDF2 import PdfFileMerger
反正导入的模块是有缓存的,一个导入多次也不用担心
I extracted and placed the PyPDF2 1.26.0 toolkit into my plugin directory
我不知道你的 "plugin directory" 是什么,但这不是安装 python 包的方法。您想改用 pip
之类的东西,最好使用 virtualenv
.
ImportError: No module named report.PyPDF2.PyPDF2
我假设第一个 "PyPDF2" 目录是 github 根目录(参见 https://github.com/mstamy2/PyPDF2). This directory is not a proper python package(它没有 __init__.py
文件)但是项目的目录。你想要的是在 "report" 中只有 "second-level" PyPDF2 目录( 是 实际的 python 包),然后使用from report.PyPDF2 import PdfFileMerger
.
但是再说一次,这不是安装 python 软件包的正确方法,参见上面的内容。
def pdf_merger(self):
# Import PyPDF2
sys.path.append(str(self.plugin_dir) + '/report/PyPDF2')
from PyPDF2 import PdfFileMerger
这将一遍又一遍地附加到 sys.path
(如果您的进程运行数周或数月,这可能确实最终会导致内存问题,具体取决于此操作的频率)函数被调用)。 IOW:不要那样做。正确安装 PyPDF2 作为依赖项(再一次,pip
和 virtualenv
是你的朋友)或者 至少 只安装 "inner" PyPDF2 包作为上面有解释。
请注意,这里的问题不是一遍又一遍地导入相同的模块(第一次导入将缓存该模块),而是一遍又一遍地附加到 sys.path
。 "local" 导入的唯一问题是性能受到非常轻微的影响,但您可能永远不会注意到它,除非这是一个在非常紧密的循环中调用的关键函数。
此外,当我们在做的时候:
sys.path.append(str(self.plugin_dir) + '/report/PyPDF2')
1/ 无需将 self.plugin_dir
传递给 str
(它已经是一个),并且
2/ 硬编码路径分隔符是一个非常糟糕的主意 - 你想要 os.path.join(self.plugin_dir, 'report', 'PyPDF2')
而不是(在这种情况下你实际上想要 none - 单独留下 sys.path
并正确安装 PyPDF2)
我提取 PyPDF2 1.26.0 工具包并将其放入我的插件目录中。层次结构如下所示:
plugin
|__example.py
|__report
|__PyPDF2
|__(PyPDF2 contents)
在 example.py
文件的开头,我尝试使用以下方法导入 PyPDF2 模块:
from report.PyPDF2.PyPDF2 import PdfFileMerger
不幸的是,这会导致错误:
ImportError: No module named report.PyPDF2.PyPDF2
但我可以使用 sys
:
import os, sys
class plugin:
def __init__(self, iface):
self.iface = iface
self.plugin_dir = os.path.dirname(__file__)
...
def pdf_merger(self):
# Import PyPDF2
sys.path.append(str(self.plugin_dir) + '/report/PyPDF2')
from PyPDF2 import PdfFileMerger
merger = PdfFileMerger()
return merger
def func(self):
merger = self.pdf_merger()
...
问题是 func()
会被调用多次,所以每次 from PyPDF2 import PdfFileMerger
都会被调用 运行。这会导致任何问题(即内存问题等)吗?为什么我不能使用 from report.PyPDF2.PyPDF2 import PdfFileMerger
导入模块?
你试过了吗:
from report.PyPDF2 import PdfFileMerger
反正导入的模块是有缓存的,一个导入多次也不用担心
I extracted and placed the PyPDF2 1.26.0 toolkit into my plugin directory
我不知道你的 "plugin directory" 是什么,但这不是安装 python 包的方法。您想改用 pip
之类的东西,最好使用 virtualenv
.
ImportError: No module named report.PyPDF2.PyPDF2
我假设第一个 "PyPDF2" 目录是 github 根目录(参见 https://github.com/mstamy2/PyPDF2). This directory is not a proper python package(它没有 __init__.py
文件)但是项目的目录。你想要的是在 "report" 中只有 "second-level" PyPDF2 目录( 是 实际的 python 包),然后使用from report.PyPDF2 import PdfFileMerger
.
但是再说一次,这不是安装 python 软件包的正确方法,参见上面的内容。
def pdf_merger(self):
# Import PyPDF2
sys.path.append(str(self.plugin_dir) + '/report/PyPDF2')
from PyPDF2 import PdfFileMerger
这将一遍又一遍地附加到 sys.path
(如果您的进程运行数周或数月,这可能确实最终会导致内存问题,具体取决于此操作的频率)函数被调用)。 IOW:不要那样做。正确安装 PyPDF2 作为依赖项(再一次,pip
和 virtualenv
是你的朋友)或者 至少 只安装 "inner" PyPDF2 包作为上面有解释。
请注意,这里的问题不是一遍又一遍地导入相同的模块(第一次导入将缓存该模块),而是一遍又一遍地附加到 sys.path
。 "local" 导入的唯一问题是性能受到非常轻微的影响,但您可能永远不会注意到它,除非这是一个在非常紧密的循环中调用的关键函数。
此外,当我们在做的时候:
sys.path.append(str(self.plugin_dir) + '/report/PyPDF2')
1/ 无需将 self.plugin_dir
传递给 str
(它已经是一个),并且
2/ 硬编码路径分隔符是一个非常糟糕的主意 - 你想要 os.path.join(self.plugin_dir, 'report', 'PyPDF2')
而不是(在这种情况下你实际上想要 none - 单独留下 sys.path
并正确安装 PyPDF2)