Zac*_*han 2 python python-import python-3.6
我有这样的文件夹结构,每次尝试使用相对导入时,都会出现错误
\n\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 graphics\n\xe2\x94\x82 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 __init__.py\n\xe2\x94\x82 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 A\n\xe2\x94\x82 \xe2\x94\x82 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 __init__.py\n\xe2\x94\x82 \xe2\x94\x82 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 grok.py\n\xe2\x94\x82 \xe2\x94\x82 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 spam.py\n \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 B\n \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 __init__.py\n \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 bar.py\n\n\nspam.py/\n def func():\n pass\nbar.py/\n def f():\n pass\nRun Code Online (Sandbox Code Playgroud)\n\n所有这些代码都在 grok.py 中进行了测试:
\n\nfrom . import spam\n# ImportError: cannot import name 'spam'\n\nfrom .spam import func\n# ModuleNotFoundError: No module named '__main__.spam'; '__main__' \nis not a package\n\nfrom ..B import bar\n# ValueError: attempted relative import beyond top-level package\nRun Code Online (Sandbox Code Playgroud)\n\n以下代码均不会导致任何错误:
\n\nfrom graphics.A import spam\nfrom graphics.A.spam import func\nfrom graphics.B import bar\nfrom graphics.B.bar import f\nRun Code Online (Sandbox Code Playgroud)\n
我认为当你说“在 grok.py 中测试”时,你正在像这样运行它:
\n\npython3 graphics/A/grok.py\npython3 A/grok.py\npython3 grok.py\nRun Code Online (Sandbox Code Playgroud)\n\n\n\n\n\n\n请注意,相对导入基于当前模块的名称。由于主模块的名称始终为“
\n__main__”,\n 用作 Python 应用程序主模块的模块\n 必须始终使用绝对导入。
当您运行 时grok.py,它会被视为主模块,并且仅当您使用绝对导入时导入才会起作用(假设您没有对 进行任何更改sys.path,我们稍后会介绍)。print(__name__)您可以通过将其放在grok.py 的开头来测试,它将打印出“__main__,它将打印出“ ”。
如果您在调用您的图形包下有一个单独的 python 文件(例如),您的相对导入实际上将会起作用main.pygrok将会起作用:
\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 graphics\n\xe2\x94\x82 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 __init__.py\n| \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 main.py <<---- add this\n\xe2\x94\x82 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 A\n\xe2\x94\x82 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 B\nRun Code Online (Sandbox Code Playgroud)\n\n在 中main.py,我们只需导入grok模块:
from A import grok\nRun Code Online (Sandbox Code Playgroud)\n\n在grok.py,让我们测试相对导入:
from . import spam\nspam.spam_func()\n\nfrom .spam import spam_func\nspam_func()\n\nfrom B import bar\nbar.bar_func()\nRun Code Online (Sandbox Code Playgroud)\n\n在spam.py:
def spam_func():\n print("spammy")\nRun Code Online (Sandbox Code Playgroud)\n\n在bar.py:
def bar_func():\n print("barry")\nRun Code Online (Sandbox Code Playgroud)\n\n当你跑步时main.py:
graphics$ python3 main.py\nspammy\nspammy\nbarry\nRun Code Online (Sandbox Code Playgroud)\n\n您不会收到任何先前的错误。相对导入有效。请注意,要从 导入B,我使用的from B是from ..B。这是因为导入路径是从main.py. 您可以通过将其添加到顶部来测试这一点main.py:
import sys\nprint(sys.path)\n# prints a list, [\'/path/to/graphics/\',...]\nRun Code Online (Sandbox Code Playgroud)\n\n如果您from ..B这样做,这意味着/path/to/graphics/../当然没有该B模块(因此,您将得到“尝试相对导入超出顶级包”错误)
现在假设您不想使用单独的程序main.py并且想grok.py直接运行。您可以做的就是手动将包的路径添加graphics到sys.path. 然后你可以from A做from Bgrok.py。
import sys\nsys.path.append("/full/path/to/graphics/")\n\nfrom A import spam\nspam.spam_func()\n\nfrom B import bar\nbar.bar_func() \nRun Code Online (Sandbox Code Playgroud)\n\n如果您想“破解” sys.path,我建议您阅读更多内容sys.path并检查其他相关帖子,这些帖子讨论了添加路径的方法sys.path相关帖子。
| 归档时间: |
|
| 查看次数: |
2350 次 |
| 最近记录: |