无法导入 class,尽管我已经有 __init__.py 个文件
Unable to import class even though I already have __init__.py files
我正在尝试将不同目录中的 class 导入另一个文件,但似乎无法正常工作。我知道这个问题已经被问了很多,我已经查看了多个 Whosebug 解决方案并在 https://docs.python.org/3/tutorial/modules.html#packages
1: Importing files from different folder
2: import python file in another directory failed
我想尝试使用仅包含 __init__.py
文件的方法,而不是执行 import sys
我的目录结构如下:
django_vue/
__init__.py
devices/
__init__.py
models.py
lib/
__init__.py
my_file.py
我正在尝试通过以下方式将 class Device
从 /django_vue/devices/models.py
导入到 /django_vue/lib/my_file.py
:
from devices.models import Device
然而,当我这样做时,我仍然得到错误:
from devices.models import Device
ModuleNotFoundError: No module named 'devices'
我不确定我做错了什么,因为我在两个目录中都已经有了 __init__
文件。任何帮助表示赞赏。我也是 运行 python 3.6.
将 __init__
文件替换为 __main__
。
这是我正在使用的文件夹结构。
.
└── django_vue
├── devices
│ └── models.py
└── lib
└── file.py
当你运行
$ python file.py
python 无法知道目录外的内容。
python 不能像那样返回然后进入 devices/
。
解决此问题的最简单方法是将文件夹 devices/
添加到 sys.path
。当 python 导入模块时,它会从 sys.path
中搜索模块。将路径添加到 devices/
将使其可用于导入。
这是我的文件。
# models.py
Device = 'device'
# file.py
import sys
sys.path.append('..') # adds the parent dir (which is django-vue/) to path
# django-vue dir has devices/ so now this is available for imports
# importing this works now
from devices.models import Device
print(Device)
输出
django_vue/lib$ python3 file.py
device
想一想你在 my_file.py
里面并导入一个叫做 devices
的东西。
python
怎么知道 devices
这个名字是从哪里来的。
它不会在整个云端硬盘中搜索 module/package
相对导入
改用相对导入。写 from ..devices.models import Device
。这告诉 python 向上一个目录到父目录,它会在那里找到 devices
包。您的 lib
模块现在应该作为 模块
如果您 运行 直接 my_file.py 包(如 python C:/django_vue/lib/my_file.py
)
您仍然会收到错误消息。不一样的错误;新错误将类似于
ImportError: attempted relative import with no known parent package
发生这种情况是因为您实际上 运行宁 my_file.py
如果您考虑一下,为什么要 运行 my_file.py
本身,因为它显然是包的一部分。也许您只是在测试使用包时导入是否有效。这样做的问题是它让你的包相对导入看起来不起作用 即使这实际上有效.
在django_vue中创建一个main.py
并写入from lib import my_file
。这将 运行 你的 my_file.py
你会发现没有错误。
这里发生了什么
你听说过__package__
吗?
如果你把 print(str(__package__))
放在你的 my_file.py
和 运行 my_file.py
直接你会看到它打印 None
.
但是,如果您 运行 main.py
(您刚刚创建的),您会看到当它到达 my_file.py
时,__package__
实际上将被定义为某物。
啊啊... 你看现在这一切都说得通了;您最初遇到的错误是关于 no known parent package
的。如果 __package__
未定义,则意味着没有相关父包,因为该文件显然是直接 运行 而不是作为包的一部分。
考虑绝对导入
您可能还想考虑使用绝对导入,因为如果您正在处理包,您可能会在开发时更改它的目录结构。因此您需要不断更改受影响文件的导入引用。
尽管您可以找到带有 python 扩展名的 IDE,当您更改目录时,它会自动添加到此。我相信 VS Code
会自动执行此操作。
我正在尝试将不同目录中的 class 导入另一个文件,但似乎无法正常工作。我知道这个问题已经被问了很多,我已经查看了多个 Whosebug 解决方案并在 https://docs.python.org/3/tutorial/modules.html#packages
1: Importing files from different folder 2: import python file in another directory failed
我想尝试使用仅包含 __init__.py
文件的方法,而不是执行 import sys
我的目录结构如下:
django_vue/
__init__.py
devices/
__init__.py
models.py
lib/
__init__.py
my_file.py
我正在尝试通过以下方式将 class Device
从 /django_vue/devices/models.py
导入到 /django_vue/lib/my_file.py
:
from devices.models import Device
然而,当我这样做时,我仍然得到错误:
from devices.models import Device
ModuleNotFoundError: No module named 'devices'
我不确定我做错了什么,因为我在两个目录中都已经有了 __init__
文件。任何帮助表示赞赏。我也是 运行 python 3.6.
将 __init__
文件替换为 __main__
。
这是我正在使用的文件夹结构。
.
└── django_vue
├── devices
│ └── models.py
└── lib
└── file.py
当你运行
$ python file.py
python 无法知道目录外的内容。
python 不能像那样返回然后进入 devices/
。
解决此问题的最简单方法是将文件夹 devices/
添加到 sys.path
。当 python 导入模块时,它会从 sys.path
中搜索模块。将路径添加到 devices/
将使其可用于导入。
这是我的文件。
# models.py
Device = 'device'
# file.py
import sys
sys.path.append('..') # adds the parent dir (which is django-vue/) to path
# django-vue dir has devices/ so now this is available for imports
# importing this works now
from devices.models import Device
print(Device)
输出
django_vue/lib$ python3 file.py
device
想一想你在 my_file.py
里面并导入一个叫做 devices
的东西。
python
怎么知道 devices
这个名字是从哪里来的。
它不会在整个云端硬盘中搜索 module/package
相对导入
改用相对导入。写 from ..devices.models import Device
。这告诉 python 向上一个目录到父目录,它会在那里找到 devices
包。您的 lib
模块现在应该作为 模块
如果您 运行 直接 my_file.py 包(如 python C:/django_vue/lib/my_file.py
)
您仍然会收到错误消息。不一样的错误;新错误将类似于
ImportError: attempted relative import with no known parent package
发生这种情况是因为您实际上 运行宁 my_file.py
如果您考虑一下,为什么要 运行 my_file.py
本身,因为它显然是包的一部分。也许您只是在测试使用包时导入是否有效。这样做的问题是它让你的包相对导入看起来不起作用 即使这实际上有效.
在django_vue中创建一个main.py
并写入from lib import my_file
。这将 运行 你的 my_file.py
你会发现没有错误。
这里发生了什么
你听说过__package__
吗?
如果你把 print(str(__package__))
放在你的 my_file.py
和 运行 my_file.py
直接你会看到它打印 None
.
但是,如果您 运行 main.py
(您刚刚创建的),您会看到当它到达 my_file.py
时,__package__
实际上将被定义为某物。
啊啊... 你看现在这一切都说得通了;您最初遇到的错误是关于 no known parent package
的。如果 __package__
未定义,则意味着没有相关父包,因为该文件显然是直接 运行 而不是作为包的一部分。
考虑绝对导入
您可能还想考虑使用绝对导入,因为如果您正在处理包,您可能会在开发时更改它的目录结构。因此您需要不断更改受影响文件的导入引用。
尽管您可以找到带有 python 扩展名的 IDE,当您更改目录时,它会自动添加到此。我相信 VS Code
会自动执行此操作。