类导入其他类错误
本教程将介绍类导入其他类错误的处理方法,这篇教程是从别的地方看到的,然后加了一些国外程序员的疑问与解答,希望能对你有所帮助,好了,下面开始学习吧。
问题描述
我有三个脚本:
C:codevoiceTermmaster.py:
from voice_terminal_module.voice_terminal import VoiceTerminal
vterm = VoiceTerminal()
C:codevoiceTermvoice_terminal_modulevoice_terminal.py:
from chatbot_module.chatbot_module import Chatbot
class VoiceTerminal:
print("INITIALIZING VOICE TERMINAL")
cb = Chatbot()
C:codevoiceTermvoice_terminal_modulechatbot_modulechatbot_module.py:
class Chatbot:
print("CHATBOT INITIALIZED")
奇怪的是:当我运行chat bot_mode.py时,它会工作,如果我运行VOICE_Terminal.py,它会工作。但是,由于某些原因,master.py会出错,并显示以下消息:
Traceback (most recent call last):
File "c:codevoiceTermmaster.py", line 1, in <module>
from voice_terminal_module.voice_terminal import VoiceTerminal
File "c:codevoiceTermvoice_terminal_modulevoice_terminal.py", line 1, in <module>
from chatbot_module.chatbot_module import Chatbot
ModuleNotFoundError: No module named 'chatbot_module'
为什么它有时起作用,但有时不起作用?
推荐答案
一般导入指南(供您自己编写)
我确定现在应该有一个副本,但我找不到,所以我正在写一篇完整的文章。
要正确解决问题,您必须注意两件事:
确保sys.path
--Python搜索模块的路径--包括项目根目录的路径。
确保代码中的import
语句编写为使用该路径。
搜索路径
对于第一部分,您必须了解sys.path
是怎么工作的。这是一个文件夹列表,将在启动时自动设置(,就像sys.argv
一样)。
正常情况下,它将是一个包含以下内容的列表:
的路径(该路径的详细信息将取决于怎么启动Python;当直接从同一目录运行.py
文件时,通常为''
,如果您这样做,则为另一个目录的路径,例如python somewhere/else/file.py
,使用-m
开关时为显式路径)
系统库路径
虚拟环境库的路径(如果虚拟环境处于活动状态)
用户显式安装的内容的路径
您修改此列表,这将对以后的import
语句产生预期影响;但您。
为确保项目根目录位于路径上,通常只需项目--理想情况下应安装到虚拟环境中。详情请参考Python packaging guide。如果做不到这一点,请确保仅从包含顶级代码的文件夹外部启动项目。在OP的例子中,这意味着C:code
。这将确保C:code
(或等效项)处于sys.path
,然后我们可以依赖它进行第二步。
导入
我们基本上可以通过两种方式做到这一点:通过指定根目录的路径,或者通过指定当前源文件的路径。阅读有关相对导入here和here的堆栈溢出的详细信息。
绝对导入
,我们都希望将项目的根文件夹(此处为)视为。对于绝对导入,这意味着我们将始终在导入路径中提及根文件夹名称。
因此:
在C:codevoiceTermmaster.py
中:from voiceTerm.voice_terminal_module.voice_terminal import VoiceTerminal
在C:codevoiceTermvoice_terminal_modulevoice_terminal.py
中:from voiceTerm.voice_terminal_module.chatbot_module.chatbot_module import Chatbot
(您不会真的想在文件夹或文件名中包含_module
。它并没有真正增加信息,使输入变得相当困难,而且实际上有点误导。)
我们还可以import
整个模块:import voiceTerm.master
,import voiceTerm.voice_terminal_module.voice_terminal
;import voiceTerm.voice_terminal_module.chatbot_module.chatbot_module
。此外,通过将文件命名为__init__.py
,我们可以将该文件夹作为导入:import voiceTerm
;import voiceTerm.voice_terminal_module
;import voiceTerm.voice_terminal_module.chatbot_module
。我们还可以从以下包之一导入模块:from voiceTerm import master
;from voiceTerm.voice_terminal_module import voice_terminal
;from voiceTerm.voice_terminal_module.chatbot_module import chatbot_module
。
相对进口量
对于相对导入,我们必须使用from
语法,并且我们只能从我们自己的包层次结构中导入内容。然而,我们的优势在于,我们不必指定完整路径,而且我们可以重命名包,而不必编辑代码。我个人的建议是在可能的情况下使用相对导入;这也与从系统库或其他第三方程序包导入有很强的视觉区别。
对于相对导入,首先使用相对导入路径指定要从中导入的包或子包。从单个.
开始,我们从当前目录开始,在同一文件夹中查找另一个模块或包。
因此:
inC:codevoiceTermmaster.py
:from .voice_terminal_module.voice_terminal import VoiceTerminal
导入类;from .voice_terminal_module import voice_terminal
导入模块。
inC:codevoiceTermvoice_terminal_modulevoice_terminal.py
:from .chatbot_module.chatbot_module import Chatbot
导入类;from .chatbot_module import chatbot_module
导入模块。
其他.
在包层次结构中向上导航(但我们不能以这种方式超出根目录)。例如,from ... import master
从下层chatbot_module.py
导入顶层master.py
。(当然,这在本例中实际上不起作用,因为它将是循环导入。)要从同一目录导入另一个源文件(作为模块),只需from . import other_file
。你明白了。
好了关于类导入其他类错误的教程就到这里就结束了,希望趣模板源码网找到的这篇技术文章能帮助到大家,更多技术教程可以在站内搜索。