เหตุใดจึงต้องใช้ sys.path.append (path) แทน sys.path.insert (1, path)


89

แก้ไข:ขึ้นอยู่กับความคิดเห็น Ulf Rompe ของมันเป็นสิ่งสำคัญที่คุณใช้ "1" แทน "0"มิฉะนั้นคุณจะทำลายsys.path

ฉันทำ python มาระยะหนึ่งแล้ว (มากกว่าหนึ่งปี) และฉันมักจะสับสนว่าทำไมคนถึงแนะนำให้คุณใช้sys.path.append()แทนsys.path.insert(). ให้ฉันสาธิต

สมมติว่าฉันกำลังทำงานกับโมดูลชื่อ PyWorkbooks (ซึ่งติดตั้งบนคอมพิวเตอร์ของฉัน) แต่ฉันกำลังทำงานกับโมดูลอื่นพร้อมกัน (สมมติว่า PyJob) ที่รวม PyWorkbooks ขณะที่ฉันทำงานกับ PyJob ฉันพบข้อผิดพลาดใน PyWorkbooks ซึ่งฉันกำลังแก้ไขดังนั้นฉันจึงต้องการนำเข้าเวอร์ชันสำหรับการพัฒนา

มีหลายวิธีในการทำงานทั้งสองอย่าง (เช่นฉันสามารถวางโครงการ PyWorkbooks ไว้ใน PyJob ได้) แต่บางครั้งฉันก็ยังต้องเล่นกับเส้นทาง อย่างไรก็ตามฉันไม่สามารถทำsys.path.append()กับโฟลเดอร์ที่ PyWorkbooks อยู่ได้ ทำไม? เพราะ python จะค้นหา PyWorkbooks ที่ติดตั้งไว้ก่อน!

นี่คือเหตุผลที่คุณต้องทำ sys.path.insert (1, path_to_dev_pyworkbooks)

สรุป:

sys.path.append(path_to_dev_pyworkbooks)
import PyWorkbooks # does NOT import dev pyworkbooks, imports installed one

หรือ:

sys.path.insert(1, path_to_dev_pyworkbooks) # based on comments you should use **1 not 0**
import PyWorkbooks # imports correct file

สิ่งนี้ทำให้ฉันมีอาการแฮงค์อยู่สองสามครั้งในอดีตและฉันจะชอบมากถ้าเรา (ในฐานะชุมชน) เริ่มแนะนำ sys.path.insert(1, path)ราวกับว่าคุณกำลังแทรกเส้นทางด้วยตนเองฉันคิดว่ามันปลอดภัยที่จะบอกว่านั่นคือเส้นทางที่คุณต้องการ ใช้!

หรือว่าฉันมีอะไรผิดปกติ? เป็นคำถามที่บางครั้งรบกวนจิตใจฉันและฉันก็อยากเปิด!


3
ฉันทำเสร็จแล้วsys.path.insert(1, dev_folder)แต่ยังไม่พบโมดูล dev และใช้เฉพาะโมดูลที่ติดตั้งเท่านั้น ฉันจะแก้ไขปัญหานี้ได้อย่างไร
endolith

คำตอบ:


47

หากคุณมีแพ็กเกจ / โมดูลหลายเวอร์ชันคุณจำเป็นต้องใช้Virtualenv (เน้นของฉัน):

virtualenv เป็นเครื่องมือในการสร้างสภาพแวดล้อม Python ที่แยกได้

ปัญหาพื้นฐานที่ได้รับการแก้ไขคือหนึ่งในการอ้างอิงและเวอร์ชันและสิทธิ์ทางอ้อม ลองนึกภาพคุณมีแอปพลิเคชันที่ต้องการ LibFoo เวอร์ชัน 1 แต่แอปพลิเคชันอื่นต้องการเวอร์ชัน 2 คุณจะใช้ทั้งสองแอปพลิเคชันนี้ได้อย่างไร หากคุณติดตั้งทุกอย่างลงใน/usr/lib/python2.7/site-packages(หรือตำแหน่งมาตรฐานของแพลตฟอร์มของคุณ) มันเป็นเรื่องง่ายที่จะจบลงในสถานการณ์ที่คุณอัปเกรดแอปพลิเคชันโดยไม่ได้ตั้งใจที่ไม่ควรอัปเกรด

หรือโดยทั่วไปแล้วถ้าคุณต้องการติดตั้งแอปพลิเคชันและปล่อยไว้จะเป็นอย่างไร? หากแอปพลิเคชันทำงานการเปลี่ยนแปลงใด ๆ ในไลบรารีหรือเวอร์ชันของไลบรารีเหล่านั้นอาจทำให้แอปพลิเคชันเสียหายได้

นอกจากนี้จะเกิดอะไรขึ้นถ้าคุณไม่สามารถติดตั้งแพ็คเกจลงในsite-packagesไดเรกทอรีส่วนกลางได้? ตัวอย่างเช่นบนโฮสต์ที่ใช้ร่วมกัน

ในกรณีเหล่านี้virtualenvสามารถช่วยคุณได้ สร้างสภาพแวดล้อมที่มีไดเร็กทอรีการติดตั้งของตัวเองที่ไม่แชร์ไลบรารีกับสภาพแวดล้อม Virtualenv อื่น ๆ (และเป็นทางเลือกที่จะไม่เข้าถึงไลบรารีที่ติดตั้งทั่วโลก)

นั่นเป็นเหตุผลที่ผู้คนพิจารณา insert(0, ผิด - เป็นวิธีแก้ปัญหาที่ไม่สมบูรณ์และหยุดชะงักสำหรับปัญหาในการจัดการสภาพแวดล้อมที่หลากหลาย


ขอบคุณฉันรู้คร่าวๆว่ามีอะไรแบบนี้ แต่ฉันยังไม่ได้ตรวจสอบเลยจนถึงตอนนี้ ดังนั้นสิ่งที่ฉันต้องทำคือเรียกใช้ทุกอย่างจากล่ามในสภาพแวดล้อมเสมือนจริง ... ที่สามารถทำงานได้เช่นกัน ขอบคุณ!
Garrett Berg

1
นี่เป็นคำแนะนำ แต่ไม่ได้ตอบคำถามโดยตรง (เช่นฉันมีเหตุผลที่ชัดเจนที่จะไม่ใช้virtualenvและฉันกำลังมองหาคำตอบที่เกี่ยวข้องกับ OP)
StephenBoesch

@javadba นั่นอาจจะเป็นจริงสำหรับกรณีของคุณ venvแต่คนส่วนใหญ่ถามคำถามนี้ควรจะใช้
agf

46

หากคุณจำเป็นต้องใช้ sys.path.insert จริงๆให้ลองออกจาก sys.path [0] ตามที่เป็นอยู่:

sys.path.insert(1, path_to_dev_pyworkbooks)

สิ่งนี้อาจมีความสำคัญเนื่องจากรหัสของบุคคลที่สามอาจอาศัยความสอดคล้องของเอกสาร sys.path :

ตามที่กำหนดค่าเริ่มต้นเมื่อเริ่มต้นโปรแกรมรายการแรกของรายการนี้คือ path [0] คือไดเร็กทอรีที่มีสคริปต์ที่ใช้ในการเรียกใช้ตัวแปล Python


13

คุณกำลังสับสนแนวคิดของการต่อท้ายและการเติมเงินล่วงหน้า รหัสต่อไปนี้กำลังรออยู่:

sys.path.insert(1,'/thePathToYourFolder/')

จะวางข้อมูลใหม่ไว้ที่จุดเริ่มต้น (อย่างที่สองเพื่อให้แม่นยำ) ของลำดับการค้นหาที่ล่ามของคุณจะดำเนินการ sys.path.append()วางสิ่งต่างๆไว้ท้ายสุดของลำดับการค้นหา

ขอแนะนำให้คุณใช้บางอย่างเช่นvirtualenvแทนที่จะเข้ารหัสไดเรกทอรีแพ็คเกจของคุณด้วยตนเองในPYTHONPATHทุกครั้ง สำหรับการตั้งค่าระบบนิเวศต่างๆที่แยกแพ็กเกจไซต์ของคุณและเวอร์ชันที่เป็นไปได้ของ python โปรดอ่านสองบล็อกนี้:

  1. การแนะนำระบบนิเวศหลาม

  2. bootstrapping python สภาพแวดล้อมเสมือน

หากคุณตัดสินใจที่จะย้ายไปตามเส้นทางสู่การแยกสภาพแวดล้อมคุณจะได้รับประโยชน์อย่างแน่นอนโดยดูใน Virtualenvwrapper: http://www.doughellmann.com/docs/virtualenvwrapper/


1
ลิงก์ "การแนะนำระบบนิเวศ python" "สภาพแวดล้อมเสมือนจริงของ bootstrapping python" ได้หยุดให้บริการแล้วโปรดพิจารณาปรับปรุงใหม่
Pradeep Singh
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.