基本 Python 导入机制
Basic Python import mechanics
我有以下目录树:
project/
A/
__init__.py
foo.py
TestA/
__init__.py
testFoo.py
testFoo 的内容是:
import unittest
from A import foo
来自 project
目录我 运行 python testA/testFoo.py
我得到一个ModuleNotFoundError No module named A
我有两个问题:如何从 TestA.testFoo 导入和 运行 A.foo 以及为什么 Python 中的导入逻辑如此难以理解?有没有什么调试技巧可以快速解决这类问题,很抱歉我不得不用这些基本问题来打扰你?
首先将文件夹project/testA
添加到系统pythonpath中:
import sys
sys.path.insert(0, "/path/to/pythonfile")
然后再次尝试导入。
当你执行一个文件时,会生成一个名为pythonpath的环境变量,pythonimport使用这个变量来找到你要导入的文件,这个路径是用你正在执行的文件,它将在当前目录和包含 __init__.py
文件的子目录中搜索,如果你想从同一级别的目录导入,你需要修改你的 python 路径或更改项目的体系结构,因此执行的文件始终位于顶层。
您可以像这样包含您的 python 路径:
import sys
sys.path.insert(0, "/path/to/file.py")
您可以阅读有关导入系统的更多信息:https://docs.python.org/3/reference/import.html
我认为最好的方法是不要触及 python 路径并将您的测试目录包含到测试文件所在的目录中:
project/
A/
__init__.py
foo.py
TestA/
__init__.py
testFoo.py
然后运行将python -m unittest
命令放入你的A或项目目录,它会搜索你的当前目录和子目录进行测试并执行它。
更多关于单元测试的信息:https://docs.python.org/3/library/unittest.html
你能试试这个吗?
在子目录 TestA
中创建一个空文件 __init__.py
。并在主代码的开头添加
from __future__ import absolute_import
然后导入如下:
import A.foo as testfoo
py3中推荐的方式可能如下所示
echo $pwd
$ /home/user/project
python -m testA.testFoo
在python中执行模块python -m
的方式是替换相对引用的好方法。
您肯定找不到 A,因为 python 需要从 sys.path
、PYTHONPATH
查找模块。
并且 python 会自动将当前 top level script
添加到 sys.path
而不是 currently directory
到 sys.path
。因此,如果您在 testFoo.py
中添加 print(sys.path)
,您将看到它只会将 project/TestA
添加到 sys.path
。
换句话说,project
没有被包含在sys.path
中,那么python如何找到模块A
?
所以你必须自己将 project
文件夹添加到 sys.path
,而且,这只是 top script
中需要的,如下所示:
import unittest
import sys
import os
file_path = os.path.abspath(os.path.dirname(__file__)).replace('\', '/')
lib_path = os.path.abspath(os.path.join(file_path, '..')).replace('\', '/')
sys.path.append(lib_path)
我有以下目录树:
project/
A/
__init__.py
foo.py
TestA/
__init__.py
testFoo.py
testFoo 的内容是:
import unittest
from A import foo
来自 project
目录我 运行 python testA/testFoo.py
我得到一个ModuleNotFoundError No module named A
我有两个问题:如何从 TestA.testFoo 导入和 运行 A.foo 以及为什么 Python 中的导入逻辑如此难以理解?有没有什么调试技巧可以快速解决这类问题,很抱歉我不得不用这些基本问题来打扰你?
首先将文件夹project/testA
添加到系统pythonpath中:
import sys
sys.path.insert(0, "/path/to/pythonfile")
然后再次尝试导入。
当你执行一个文件时,会生成一个名为pythonpath的环境变量,pythonimport使用这个变量来找到你要导入的文件,这个路径是用你正在执行的文件,它将在当前目录和包含 __init__.py
文件的子目录中搜索,如果你想从同一级别的目录导入,你需要修改你的 python 路径或更改项目的体系结构,因此执行的文件始终位于顶层。
您可以像这样包含您的 python 路径:
import sys
sys.path.insert(0, "/path/to/file.py")
您可以阅读有关导入系统的更多信息:https://docs.python.org/3/reference/import.html
我认为最好的方法是不要触及 python 路径并将您的测试目录包含到测试文件所在的目录中:
project/
A/
__init__.py
foo.py
TestA/
__init__.py
testFoo.py
然后运行将python -m unittest
命令放入你的A或项目目录,它会搜索你的当前目录和子目录进行测试并执行它。
更多关于单元测试的信息:https://docs.python.org/3/library/unittest.html
你能试试这个吗?
在子目录 TestA
中创建一个空文件 __init__.py
。并在主代码的开头添加
from __future__ import absolute_import
然后导入如下:
import A.foo as testfoo
py3中推荐的方式可能如下所示
echo $pwd
$ /home/user/project
python -m testA.testFoo
在python中执行模块python -m
的方式是替换相对引用的好方法。
您肯定找不到 A,因为 python 需要从 sys.path
、PYTHONPATH
查找模块。
并且 python 会自动将当前 top level script
添加到 sys.path
而不是 currently directory
到 sys.path
。因此,如果您在 testFoo.py
中添加 print(sys.path)
,您将看到它只会将 project/TestA
添加到 sys.path
。
换句话说,project
没有被包含在sys.path
中,那么python如何找到模块A
?
所以你必须自己将 project
文件夹添加到 sys.path
,而且,这只是 top script
中需要的,如下所示:
import unittest
import sys
import os
file_path = os.path.abspath(os.path.dirname(__file__)).replace('\', '/')
lib_path = os.path.abspath(os.path.join(file_path, '..')).replace('\', '/')
sys.path.append(lib_path)