厌倦了sys.path hacks?
有大量的sys.path.append
-hacks,但是我找到了另一种解决问题的方法。
摘要
- 将代码包装到一个文件夹中(例如
packaged_stuff
)
setup.py
在使用setuptools.setup()的地方使用创建脚本。
- 使用以下命令以可编辑状态安装软件包
pip install -e <myproject_folder>
- 导入使用
from packaged_stuff.modulename import function_name
建立
起点是您提供的文件结构,包装在名为的文件夹中myproject
。
.
└── myproject
├── api
│ ├── api_key.py
│ ├── api.py
│ └── __init__.py
├── examples
│ ├── example_one.py
│ ├── example_two.py
│ └── __init__.py
├── LICENCE.md
├── README.md
└── tests
├── __init__.py
└── test_one.py
我将调用.
根文件夹,在本例中,它位于C:\tmp\test_imports\
。
api.py
作为测试用例,让我们使用以下./api/api.py
def function_from_api():
return 'I am the return value from api.api!'
test_one.py
from api.api import function_from_api
def test_function():
print(function_from_api())
if __name__ == '__main__':
test_function()
尝试运行test_one:
PS C:\tmp\test_imports> python .\myproject\tests\test_one.py
Traceback (most recent call last):
File ".\myproject\tests\test_one.py", line 1, in <module>
from api.api import function_from_api
ModuleNotFoundError: No module named 'api'
还尝试相对进口将无法正常工作:
使用from ..api.api import function_from_api
会导致
PS C:\tmp\test_imports> python .\myproject\tests\test_one.py
Traceback (most recent call last):
File ".\tests\test_one.py", line 1, in <module>
from ..api.api import function_from_api
ValueError: attempted relative import beyond top-level package
脚步
- 将setup.py文件创建到根目录
的内容为setup.py
*
from setuptools import setup, find_packages
setup(name='myproject', version='1.0', packages=find_packages())
- 使用虚拟环境
如果您熟悉虚拟环境,请激活一个,然后跳到下一步。虚拟环境的使用不是绝对必需的,但从长远来看(当您正在进行多个项目时),它们确实可以帮助您。最基本的步骤是(在根文件夹中运行)
- 创建虚拟环境
- 激活虚拟环境
source ./venv/bin/activate
(Linux,macOS)或./venv/Scripts/activate
(Win)
要了解更多信息,只需在Google上搜索“ python虚拟环境教程”或类似内容即可。除了创建,激活和停用之外,您可能根本不需要任何其他命令。
创建并激活虚拟环境后,控制台应在括号中提供虚拟环境的名称。
PS C:\tmp\test_imports> python -m venv venv
PS C:\tmp\test_imports> .\venv\Scripts\activate
(venv) PS C:\tmp\test_imports>
您的文件夹树应如下所示**
.
├── myproject
│ ├── api
│ │ ├── api_key.py
│ │ ├── api.py
│ │ └── __init__.py
│ ├── examples
│ │ ├── example_one.py
│ │ ├── example_two.py
│ │ └── __init__.py
│ ├── LICENCE.md
│ ├── README.md
│ └── tests
│ ├── __init__.py
│ └── test_one.py
├── setup.py
└── venv
├── Include
├── Lib
├── pyvenv.cfg
└── Scripts [87 entries exceeds filelimit, not opening dir]
- pip以可编辑状态安装项目
安装您的顶级包myproject
使用pip
。诀窍是-e
在执行安装时使用标志。这样,它以可编辑状态安装,并且对.py文件所做的所有编辑将自动包含在已安装的软件包中。
在根目录中,运行
pip install -e .
(注意点,它代表“当前目录”)
您还可以看到它是通过使用安装的 pip freeze
(venv) PS C:\tmp\test_imports> pip install -e .
Obtaining file:///C:/tmp/test_imports
Installing collected packages: myproject
Running setup.py develop for myproject
Successfully installed myproject
(venv) PS C:\tmp\test_imports> pip freeze
myproject==1.0
- 添加
myproject.
到您的进口中
请注意,您将只需要添加myproject.
导入否则将无法正常工作。不能使用setup.py
&导入的导入pip install
仍然可以正常工作。请参见下面的示例。
测试解决方案
现在,让我们使用api.py
上面test_one.py
定义的和下面定义的测试解决方案。
test_one.py
from myproject.api.api import function_from_api
def test_function():
print(function_from_api())
if __name__ == '__main__':
test_function()
运行测试
(venv) PS C:\tmp\test_imports> python .\myproject\tests\test_one.py
I am the return value from api.api!
*有关更多详细的setup.py示例,请参阅setuptools文档。
**实际上,您可以将虚拟环境放在硬盘上的任何位置。
sys.path
技巧,并阅读迄今为止(7年后!)发布的唯一实际解决方案。