เบื่อ sys.path hacks?
มีมากมาย sys.path.append
แฮ็กพร้อมใช้งาน แต่ฉันพบวิธีอื่นในการแก้ปัญหาในมือ
สรุป
- ล้อมโค้ดไว้ในหนึ่งโฟลเดอร์ (เช่น
packaged_stuff
)
- ใช้สร้าง
setup.py
สคริปต์ที่คุณใช้setuptools.setup ()
- Pip ติดตั้งแพคเกจในสถานะที่แก้ไขได้ด้วย
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())
- ใช้สภาพแวดล้อมเสมือนจริง
หากคุณคุ้นเคยกับสภาพแวดล้อมเสมือนให้เปิดใช้งานหนึ่งและข้ามไปยังขั้นตอนถัดไป การใช้งานของสภาพแวดล้อมเสมือนจริงนั้นไม่จำเป็นอย่างแท้จริงแต่จะช่วยคุณได้จริงในระยะยาว (เมื่อคุณมีมากกว่า 1 โครงการที่กำลังดำเนินการ .. ) ขั้นตอนพื้นฐานที่สุดคือ (เรียกใช้ในโฟลเดอร์รูท)
- สร้าง env เสมือน
- เปิดใช้งาน env เสมือน
source ./venv/bin/activate
(Linux, macOS) หรือ./venv/Scripts/activate
(Win)
หากต้องการเรียนรู้เพิ่มเติมเกี่ยวกับสิ่งนี้เพียงแค่ Google ออก "python virtual env tutorial" หรือที่คล้ายกัน คุณอาจไม่ต้องการคำสั่งอื่นใดนอกจากสร้างเปิดใช้งานและปิดใช้งาน
เมื่อคุณสร้างและเปิดใช้งานสภาพแวดล้อมเสมือนแล้วคอนโซลของคุณควรให้ชื่อของสภาพแวดล้อมเสมือนในวงเล็บ
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!
* ดูที่setuptools docsสำหรับตัวอย่าง verbose setup.py เพิ่มเติม
** ในความเป็นจริงคุณสามารถวางสภาพแวดล้อมเสมือนจริงของคุณได้ทุกที่บนฮาร์ดดิสก์ของคุณ
sys.path
แฮ็กที่ผ่านมาทั้งหมดและอ่านวิธีแก้ปัญหาจริงเท่านั้นที่โพสต์จนถึงขณะนี้ (หลังจาก 7 ปี!)