Mệt mỏi vì hack sys.path?
Có rất nhiều cách sys.path.append
thức có sẵn, nhưng tôi đã tìm thấy một cách khác để giải quyết vấn đề trong tay.
Tóm lược
- Gói mã vào một thư mục (ví dụ
packaged_stuff
)
- Sử dụng tạo
setup.py
tập lệnh trong đó bạn sử dụng setuptools.setup () .
- Pip cài đặt gói ở trạng thái có thể chỉnh sửa với
pip install -e <myproject_folder>
- Nhập khẩu bằng cách sử dụng
from packaged_stuff.modulename import function_name
Thiết lập
Điểm bắt đầu là cấu trúc tệp bạn đã cung cấp, được bọc trong một thư mục có tên 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
Tôi sẽ gọi .
thư mục gốc, và trong trường hợp ví dụ của tôi, nó được đặt tại C:\tmp\test_imports\
.
api.py
Như một trường hợp thử nghiệm, hãy sử dụng ./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()
Hãy thử chạy 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'
Cũng cố gắng nhập khẩu tương đối sẽ không làm việc:
Sử dụng from ..api.api import function_from_api
sẽ dẫn đến
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
Các bước
- Tạo một tập tin setup.py vào thư mục cấp gốc
Nội dung cho setup.py
sẽ là *
from setuptools import setup, find_packages
setup(name='myproject', version='1.0', packages=find_packages())
- Sử dụng môi trường ảo
Nếu bạn quen thuộc với môi trường ảo, hãy kích hoạt một và bỏ qua bước tiếp theo. Việc sử dụng môi trường ảo không hoàn toàn bắt buộc, nhưng chúng sẽ thực sự giúp bạn trong thời gian dài (khi bạn có hơn 1 dự án đang diễn ra ..). Các bước cơ bản nhất là (chạy trong thư mục gốc)
- Tạo env ảo
- Kích hoạt env ảo
source ./venv/bin/activate
(Linux, macOS) hoặc ./venv/Scripts/activate
(Thắng)
Để tìm hiểu thêm về điều này, chỉ cần Google tìm ra "hướng dẫn env ảo python" hoặc tương tự. Bạn có thể không bao giờ cần bất kỳ lệnh nào khác ngoài việc tạo, kích hoạt và hủy kích hoạt.
Khi bạn đã tạo và kích hoạt một môi trường ảo, bảng điều khiển của bạn sẽ đặt tên của môi trường ảo trong ngoặc đơn
PS C:\tmp\test_imports> python -m venv venv
PS C:\tmp\test_imports> .\venv\Scripts\activate
(venv) PS C:\tmp\test_imports>
và cây thư mục của bạn sẽ trông như thế này **
.
├── 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 cài đặt dự án của bạn trong trạng thái có thể chỉnh sửa
Cài đặt gói cấp cao nhất của bạn myproject
bằng cách sử dụng pip
. Mẹo nhỏ là sử dụng -e
cờ khi thực hiện cài đặt. Bằng cách này, nó được cài đặt ở trạng thái có thể chỉnh sửa và tất cả các chỉnh sửa được thực hiện cho các tệp .py sẽ được tự động đưa vào gói đã cài đặt.
Trong thư mục gốc, hãy chạy
pip install -e .
(lưu ý dấu chấm, nó là viết tắt của "thư mục hiện tại")
Bạn cũng có thể thấy rằng nó được cài đặt bằng cách sử dụng 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
- Thêm
myproject.
vào nhập khẩu của bạn
Lưu ý rằng bạn sẽ chỉ phải thêm myproject.
vào các mục nhập không hoạt động khác. Nhập khẩu mà làm việc mà không có setup.py
& pip install
sẽ hoạt động tốt. Xem một ví dụ dưới đây.
Kiểm tra giải pháp
Bây giờ, hãy kiểm tra giải pháp bằng cách sử dụng api.py
được xác định ở trên và test_one.py
được xác định bên dưới.
test_one.py
from myproject.api.api import function_from_api
def test_function():
print(function_from_api())
if __name__ == '__main__':
test_function()
chạy thử
(venv) PS C:\tmp\test_imports> python .\myproject\tests\test_one.py
I am the return value from api.api!
* Xem tài liệu setuptools để biết thêm ví dụ về thiết lập chi tiết.
** Trong thực tế, bạn có thể đặt môi trường ảo của mình ở bất cứ đâu trên đĩa cứng.
sys.path
hack và đọc giải pháp thực tế duy nhất được đăng cho đến nay (sau 7 năm!).