ถ้าฉันย้ายCreateUser.py
ไปที่ไดเร็กทอรี user_management หลักฉันสามารถใช้: import Modules.LDAPManager
เพื่อนำเข้าLDAPManager.py
- ใช้งานได้
กรุณาทำไม่ได้ ด้วยวิธีนี้LDAPManager
โมดูลที่ใช้CreateUser
จะไม่เหมือนกับโมดูลที่นำเข้าผ่านการนำเข้าอื่น ๆ สิ่งนี้สามารถสร้างปัญหาได้เมื่อคุณมีสถานะโกลบอลบางอย่างในโมดูลหรือระหว่างการดอง / การแกะไม่ออก หลีกเลี่ยงการนำเข้าที่ใช้ได้เฉพาะเนื่องจากโมดูลอยู่ในไดเร็กทอรีเดียวกัน
เมื่อคุณมีโครงสร้างแพ็คเกจคุณควรทำดังนี้
ใช้การนำเข้าแบบสัมพัทธ์กล่าวคือถ้าCreateUser.py
อยู่ในScripts/
:
from ..Modules import LDAPManager
ทราบว่านี้เป็น (หมายเหตุที่ผ่านมาเครียด) กำลังใจจากPEP 8เพียงเพราะรุ่นเก่าของงูหลามไม่สนับสนุนพวกเขาดีมาก แต่ปัญหานี้ถูกแก้ไขปีที่ผ่านมา ปัจจุบันรุ่นของ PEP 8 ไม่แนะนำให้พวกเขาเป็นทางเลือกที่ได้รับการยอมรับนำเข้าแน่นอน ฉันชอบพวกมันในแพ็คเกจจริงๆ
ใช้การนำเข้าแบบสัมบูรณ์โดยใช้ชื่อแพ็กเกจทั้งหมด ( CreateUser.py
ในScripts/
):
from user_management.Modules import LDAPManager
เพื่อให้ชุดที่สองทำงานได้user_management
ควรติดตั้งแพ็คเกจภายในไฟล์PYTHONPATH
. ในระหว่างการพัฒนาคุณสามารถกำหนดค่า IDE เพื่อให้สิ่งนี้เกิดขึ้นได้โดยไม่ต้องเพิ่มการโทรด้วยตนเองไปsys.path.append
ที่ใดก็ได้
นอกจากนี้ฉันพบว่ามันแปลกที่Scripts/
เป็นแพ็คเกจย่อย เนื่องจากในการติดตั้งจริงuser_management
โมดูลจะถูกติดตั้งภายใต้site-packages
found ในlib/
ไดเร็กทอรี (ไดเร็กทอรีใดที่ใช้ในการติดตั้งไลบรารีใน OS ของคุณ) ในขณะที่ควรติดตั้งสคริปต์ภายใต้bin/
ไดเร็กทอรี (ซึ่งมีไฟล์ปฏิบัติการสำหรับ OS ของคุณ)
ในความเป็นจริงผมเชื่อว่าจะไม่ได้อยู่ภายใต้การScript/
user_management
ควรอยู่ในระดับเดียวกันของuser_management
. ด้วยวิธีนี้คุณไม่จำเป็นต้องใช้-m
แต่คุณต้องตรวจสอบให้แน่ใจว่าสามารถพบแพ็คเกจได้ (อีกครั้งเป็นเรื่องของการกำหนดค่า IDE การติดตั้งแพ็คเกจอย่างถูกต้องหรือใช้PYTHONPATH=. python Scripts/CreateUser.py
เพื่อเรียกใช้สคริปต์ด้วยพา ธ ที่ถูกต้อง)
โดยสรุปลำดับชั้นที่ฉันจะใช้คือ:
user_management (package)
|
|------- __init__.py
|
|------- Modules/
| |
| |----- __init__.py
| |----- LDAPManager.py
| |----- PasswordManager.py
|
Scripts/ (*not* a package)
|
|----- CreateUser.py
|----- FindUser.py
จากนั้นรหัสของCreateUser.py
และFindUser.py
ควรใช้การนำเข้าแบบสัมบูรณ์เพื่อนำเข้าโมดูล:
from user_management.Modules import LDAPManager
ในระหว่างการติดตั้งคุณต้องแน่ใจว่าuser_management
ลงท้ายที่ใดที่หนึ่งในPYTHONPATH
และสคริปต์ภายในไดเร็กทอรีสำหรับไฟล์ปฏิบัติการเพื่อให้สามารถค้นหาโมดูลได้ ในระหว่างการพัฒนาคุณต้องอาศัยคอนฟิกูเรชัน IDE หรือคุณเปิดCreateUser.py
การเพิ่มScripts/
ไดเร็กทอรีหลักในPYTHONPATH
(ฉันหมายถึงไดเร็กทอรีที่มีทั้งสองuser_management
และScripts
):
PYTHONPATH=/the/parent/directory python Scripts/CreateUser.py
หรือคุณสามารถแก้ไขPYTHONPATH
ทั่วโลกเพื่อที่คุณจะได้ไม่ต้องระบุสิ่งนี้ในแต่ละครั้ง ในระบบปฏิบัติการยูนิกซ์ (linux, Mac OS X เป็นต้น) คุณสามารถแก้ไขเชลล์สคริปต์เพื่อกำหนดPYTHONPATH
ตัวแปรภายนอกได้บน Windows คุณต้องเปลี่ยนการตั้งค่าตัวแปรสภาพแวดล้อม
ภาคผนวกฉันเชื่อว่าหากคุณใช้ python2 จะเป็นการดีกว่าที่จะหลีกเลี่ยงการนำเข้าสัมพัทธ์โดยปริยายโดยใส่:
from __future__ import absolute_import
ที่ด้านบนสุดของโมดูลของคุณ วิธีนี้import X
มักจะหมายถึงการที่จะนำเข้าระดับบนสุดโมดูลX
และจะไม่พยายามที่จะนำเข้าX.py
ไฟล์ที่อยู่ในไดเรกทอรีเดียวกัน (ถ้าไดเรกทอรีที่ไม่ได้อยู่ในPYTHONPATH
) ด้วยวิธีนี้วิธีเดียวที่จะทำการอิมพอร์ตแบบสัมพัทธ์คือการใช้Explicit syntax (the from . import X
) ซึ่งดีกว่า ( Explicit ดีกว่า implicit )
วิธีนี้จะช่วยให้แน่ใจว่าคุณจะไม่ใช้การนำเข้าสัมพัทธ์โดยนัย "ปลอม" เนื่องจากสิ่งเหล่านี้จะImportError
ส่งสัญญาณอย่างชัดเจนว่ามีบางอย่างผิดปกติ มิฉะนั้นคุณสามารถใช้โมดูลที่ไม่ใช่สิ่งที่คุณคิดได้
python -m user_management.Scripts.CreateUser