我在GitHub上见过许多Python项目,它们使用非常漂亮和干净的导入,它们在项目的根目录中定义自己的类型,并从内部的子包中导入它们。
例如,您可以具有如下的目录结构:
project
- foo
- foo.py
- bar
- baz
- baz.py
- bar.py
main.py
types.pytypes.py中可能有一些类是项目中的核心数据类型。
# types.py
from dataclasses import dataclass
@dataclass(frozen=True)
class ImportantType:
"""This is a core type within the project that's used by sub-packages."""
foo: str
bar: str然后,有趣的是,在任何一个子包中,您都可以找到如下代码:
# foo/foo.py
from project import types
def example():
f = types.ImportantType("foo", "bar")
# does some processing on f.据我所知,Python导入通常不是这样工作的。但是,能够将数据模型放在项目的根目录中,并且能够导入相对于项目根目录的包和模块,这似乎是非常干净的。
为了能够像这样使用导入,您如何设置您的项目?
thefuck就是一个使用它的项目的例子,这里有一个到the file importing from root的链接。
免责声明:我已经搜索了代码,他们没有向PYTHONPATH添加包,也没有使用sys.path方法。
发布于 2021-04-18 02:25:59
只有在不安装包的情况下才需要设置PYTHONPATH。在内部,Python搜索sys.path以查找您使用from或import关键字指定的任何内容。路径在根目录停止,这些子目录告诉python它需要搜索特定的目录序列来找到正确的文件。
rootdir/
project/
__init__.py
foo/
__init__.py # All __init__.py file can be empty
hello_module.py
tests/test_import.py
setup.py
>>>> print(sys.path)
['', '/usr/local/Cellar/python@3.9/3.9.2_1/Frameworks/Python.framework/Versions/3.9/lib/python39.zip', '/usr/local/Cellar/python@3.9/3.9.2_1/Frameworks/Python.framework/Versions/3.9/lib/python3.9', '/usr/local/Cellar/python@3.9/3.9.2_1/Frameworks/Python.framework/Versions/3.9/lib/python3.9/lib-dynload', '/usr/local/lib/python3.9/site-packages', '/usr/local/Cellar/protobuf/3.14.0/libexec/lib/python3.9/site-packages']https://docs.python.org/3.5/library/sys.html#sys.path
#project/foo/hello_module.py
def example():
return ("hello module")
#tests/test_import.py
import os, sys
import unittest
class TestStringMethods(unittest.TestCase):
def test_import(self):
try:
from project.foo.hello_module import example
self.assertEqual(example().lower(), 'hello module')
except Exception:
try:
self.assertIsNone(os.environ["PYTHONPATH"], os.environ["PYTHONPATH"])
except Exception:
self.assertTrue(False, "Error PYTHONPATH not defined")
pass
if __name__ == '__main__':
unittest.main()
# setup.py
import setuptools
setuptools.setup(name='project',
version='1.0',
description='test import project',
author='somebody not me',
author_email='somebodynotme@example.net',
packages=setuptools.find_packages(
exclude=["test/"]
)
)使用PYTHONPATH测试项目
PYTHONPATH=`pwd` python3 tests/tests_import.py
.
----------------------------------------------------------------------
Ran 1 test in 0.004s
OK在未通过虚拟环境安装PYTHONPATH的情况下测试项目
## Setup venv
python3 -m venv venv
source venv/bin/activate注意venv如何添加额外的路径
python3 -c "import sys; print(sys.path)"
['', '/usr/local/Cellar/python@3.9/3.9.2_1/Frameworks/Python.framework/Versions/3.9/lib/python39.zip', '/usr/local/Cellar/python@3.9/3.9.2_1/Frameworks/Python.framework/Versions/3.9/lib/python3.9', '/usr/local/Cellar/python@3.9/3.9.2_1/Frameworks/Python.framework/Versions/3.9/lib/python3.9/lib-dynload', '/Users/somebodyotherthanme/stackoverflow/67140161/venv/lib/python3.9/site-packages']安装测试包并运行它
pip install /path/to/rootdir
python3 tests/test_import.py
python3 tests/tests_import.py
.
----------------------------------------------------------------------
Ran 1 test in 0.002s
OK
(venv) ➜ root_dir/ ls venv/lib/python3.9/site-packages/project
__init__.py __pycache__ foohttps://stackoverflow.com/questions/67140161
复制相似问题