โครงสร้างโครงการที่ดีที่สุดสำหรับแอพพลิเคชั่น Python คืออะไร? [ปิด]


730

ลองนึกภาพว่าคุณต้องการพัฒนาแอปพลิเคชั่นสำหรับผู้ใช้ปลายทาง (ไม่ใช่เว็บ) ใน Python วิธีที่ดีที่สุดในการจัดโครงสร้างลำดับชั้นโฟลเดอร์ของโครงการคืออะไร

คุณสมบัติที่พึงประสงค์คือความสะดวกในการบำรุงรักษา, IDE-friendly, ความเหมาะสมสำหรับการแยก / รวมการควบคุมแหล่งที่มาและการสร้างแพ็คเกจการติดตั้งที่ง่ายดาย

โดยเฉพาะอย่างยิ่ง:

  1. คุณใส่แหล่งที่มาที่ไหน?
  2. คุณใส่สคริปต์เริ่มต้นแอปพลิเคชันไว้ที่ไหน
  3. คุณใส่ cruft โครงการ IDE ที่ไหน
  4. คุณทำการทดสอบหน่วย / การตอบรับจากที่ไหน
  5. คุณใส่ข้อมูลที่ไม่ได้อยู่ใน Python เช่นไฟล์ config ที่ไหน
  6. คุณใส่แหล่งข้อมูลที่ไม่ใช่ Python เช่น C ++ สำหรับโมดูลส่วนขยายไบนารี pyd / so ที่ไหน?

คำตอบ:


378

ไม่สำคัญเกินไป อะไรก็ตามที่ทำให้คุณมีความสุขจะได้ผล ไม่มีกฎโง่ ๆ มากมายเพราะโครงการ Python นั้นง่าย

  • /scriptsหรือ/binสิ่งต่าง ๆ ของอินเตอร์เฟสบรรทัดคำสั่งนั้น
  • /tests สำหรับการทดสอบของคุณ
  • /lib สำหรับไลบรารีภาษา C ของคุณ
  • /doc สำหรับเอกสารส่วนใหญ่
  • /apidoc สำหรับเอกสาร API ที่สร้างจาก Epydoc

และไดเรกทอรีระดับบนสุดสามารถมี README's, Config และ whatnot

ทางเลือกที่ยากคือการใช้/srcต้นไม้หรือไม่ งูใหญ่ไม่ได้มีความแตกต่างระหว่าง/src, /libและ/binเช่น Java หรือ C มี

เนื่องจาก/srcไดเรกทอรีระดับบนสุดถูกมองว่าไม่มีความหมายไดเรกทอรีระดับบนสุดของคุณจึงอาจเป็นสถาปัตยกรรมระดับสูงสุดของแอปพลิเคชันของคุณ

  • /foo
  • /bar
  • /baz

ฉันขอแนะนำให้วางสิ่งเหล่านี้ไว้ในไดเรกทอรี "name-of-my-product" ดังนั้นถ้าคุณกำลังเขียนใบสมัครชื่อquux, /quuxไดเรกทอรีที่มีทุกสิ่งนี้เป็นชื่อ

จากนั้นอีกโปรเจ็PYTHONPATHกต์สามารถรวม/path/to/quux/fooเพื่อนำQUUX.fooโมดูล กลับมาใช้ใหม่

ในกรณีของฉันเนื่องจากฉันใช้ Komodo Edit, cuft IDE ของฉันเป็นไฟล์. KPP เดียว ฉันใส่ที่อยู่ใน/quuxไดเรกทอรีระดับบนสุดและละเว้นการเพิ่มไปยัง SVN


23
หลามโอเพนซอร์สใด ๆ ที่คุณอยากแนะนำให้จำลองโครงสร้างไดเรกทอรีของมัน?
แลนซ์พุ่ง

4
ดู Django สำหรับตัวอย่างที่ดี
S.Lott

33
ฉันไม่คิดว่า Django เป็นตัวอย่างที่ดี - เทคนิคการเล่นกับ sys.path เป็น DQ แบบทันทีในหนังสือของฉัน
Charles Duffy

18
"เคล็ดลับ" อีกครั้ง: Django เพิ่มพาเรนต์ของโฟลเดอร์รูทโปรเจ็กต์ไปยัง sys.path เพื่อให้โมดูลสามารถอิมพอร์ตเป็น "จาก project.app.module import klass" หรือ "จาก app.module import klass"
Jonathan Hartley

3
โอ้ฉันรักเคล็ดลับนี้และใช้มันตอนนี้ ฉันต้องการวางโมดูลที่ใช้ร่วมกันไว้ในไดเรกทอรีอื่นและฉันไม่ต้องการติดตั้งโมดูลทั้งระบบและฉันไม่ต้องการให้คนอื่นแก้ไข PYTHONPATH ด้วยตนเอง ถ้าคนไม่เสนออะไรที่ดีกว่านี้ฉันคิดว่านี่เป็นวิธีที่สะอาดที่สุด
Yongwei Wu

242

ตามโครงสร้างระบบไฟล์ของ Jean-Paul Calderone ของโครงการ Python :

Project/
|-- bin/
|   |-- project
|
|-- project/
|   |-- test/
|   |   |-- __init__.py
|   |   |-- test_main.py
|   |   
|   |-- __init__.py
|   |-- main.py
|
|-- setup.py
|-- README

23
Project/project/? อาชื่อแพคเกจที่สอง
Cees Timmerman

44
แฟ้มที่ปฏิบัติการได้ในโฟลเดอร์ช่องเก็บอ้างอิงโมดูลโครงการอย่างไร (ผมไม่คิดว่าไวยากรณ์หลามช่วย../ในคำสั่งการรวม)
ThorSummoner

8
@ThorSummoner ง่าย ๆ คุณติดตั้งแพ็คเกจ! ( pip install -e /path/to/Project)
Kroltan

22
มันจะยอดเยี่ยมถ้ามีคนจะซิปตัวอย่างของรูปแบบนี้ด้วย hello.py และ hello-test.py และทำให้มันพร้อมใช้งานสำหรับเรา newbs
jeremyjjbrown

8
@Bloke หลักคือการ-eตั้งค่าสถานะซึ่งติดตั้งแพคเกจเป็นแพคเกจที่แก้ไขได้นั่นคือติดตั้งมันเป็นลิงค์ไปยังโฟลเดอร์โครงการที่เกิดขึ้นจริง ปฏิบัติการสามารถเพียงแค่import projectมีการเข้าถึงโมดูล
Kroltan

232

โพสต์บล็อกนี้โดย Jean-Paul Calderoneโดยทั่วไปจะได้รับเป็นคำตอบใน #python ใน Freenode

โครงสร้างระบบแฟ้มของโครงการ Python

ทำ:

  • ตั้งชื่อไดเรกทอรีที่เกี่ยวข้องกับโครงการของคุณ ตัวอย่างเช่นถ้าโครงการของคุณมีชื่อว่า "บิด" Twistedชื่อไดเรกทอรีระดับบนสุดสำหรับแฟ้มแหล่งที่มาของ เมื่อคุณทำประชาสัมพันธ์, Twisted-2.5คุณควรจะมีคำต่อท้ายหมายเลขรุ่น:
  • สร้างไดเรกทอรีTwisted/binและใส่ไฟล์ปฏิบัติการของคุณถ้าคุณมี อย่าให้.pyส่วนขยายแก่พวกเขาแม้ว่าจะเป็นไฟล์ต้นฉบับของ Python ก็ตาม อย่าใส่รหัสใด ๆ ในพวกเขายกเว้นการนำเข้าและโทรไปยังฟังก์ชั่นหลักที่กำหนดไว้ที่อื่นในโครงการของคุณ (ลดเลือนริ้วรอยเล็กน้อย: เนื่องจากบน Windows ตัวแปลจะถูกเลือกโดยนามสกุลไฟล์ผู้ใช้ Windows ของคุณต้องการนามสกุล. py ดังนั้นเมื่อคุณทำแพ็คเกจสำหรับ Windows คุณอาจต้องการเพิ่มมันน่าเสียดายที่ไม่มีเคล็ดลับ distutils ง่าย ๆ ฉันรู้ว่าจะทำให้กระบวนการนี้เป็นอัตโนมัติโดยพิจารณาว่าใน POSIX ส่วนขยาย. py เป็นเพียงหูดในขณะที่การขาด Windows เป็นข้อผิดพลาดจริงถ้าฐานผู้ใช้ของคุณมีผู้ใช้ Windows คุณอาจต้องการเลือกที่จะมี. py ขยายได้ทุกที่)
  • หากโครงการของคุณสามารถแสดงเป็นไฟล์ต้นฉบับ Python เดียวให้ใส่ไว้ในไดเรกทอรีและตั้งชื่อสิ่งที่เกี่ยวข้องกับโครงการของคุณ ตัวอย่างเช่นTwisted/twisted.py. หากคุณต้องการไฟล์ต้นฉบับหลายไฟล์ให้สร้างแพ็คเกจแทน ( Twisted/twisted/ด้วยไฟล์ว่างTwisted/twisted/__init__.py) และวางไฟล์ต้นฉบับไว้ในนั้น ตัวอย่างเช่นTwisted/twisted/internet.py.
  • ใส่ทดสอบหน่วยของคุณในการย่อยแพคเกจของแพคเกจของคุณ (หมายเหตุ - ที่นี้หมายถึงว่าตัวเลือกเดียวหลามแฟ้มแหล่งที่มาข้างต้นเป็นเคล็ดลับ - คุณมักจะต้องไม่น้อยกว่าหนึ่งไฟล์อื่น ๆ สำหรับการทดสอบหน่วยของคุณ) ตัวอย่างเช่นTwisted/twisted/test/. Twisted/twisted/test/__init__.pyแน่นอนทำให้มันเป็นแพคเกจที่มี Twisted/twisted/test/test_internet.pyการทดสอบสถานที่ในไฟล์เช่น
  • เพิ่มTwisted/READMEและTwisted/setup.pyเพื่ออธิบายและติดตั้งซอฟต์แวร์ตามลำดับหากคุณรู้สึกดี

ไม่ได้:

  • ใส่แหล่งที่มาของคุณในไดเรกทอรีที่เรียกว่าหรือsrc libทำให้ยากต่อการรันโดยไม่ต้องติดตั้ง
  • เอาการทดสอบออกนอกแพ็คเกจ Python ของคุณ สิ่งนี้ทำให้ยากที่จะทำการทดสอบกับเวอร์ชันที่ติดตั้ง
  • สร้างแพคเกจที่เพียงมีแล้วใส่รหัสของคุณทั้งหมดลง__init__.py __init__.pyเพียงแค่สร้างโมดูลแทนที่จะเป็นแพ็คเกจมันง่ายกว่า
  • พยายามสร้างแฮ็กวิเศษเพื่อให้ Python สามารถนำเข้าโมดูลหรือแพ็คเกจของคุณโดยไม่ต้องให้ผู้ใช้เพิ่มไดเรกทอรีที่มีไดเรกทอรีนั้นไปยังเส้นทางการนำเข้าของพวกเขา (ผ่าน PYTHONPATH หรือกลไกอื่น ๆ ) คุณจะจัดการกับทุกกรณีไม่ถูกต้องและผู้ใช้จะโกรธคุณเมื่อซอฟต์แวร์ของคุณไม่ทำงานในสภาพแวดล้อมของพวกเขา

25
นี่คือสิ่งที่ฉันต้องการ "อย่าพยายามแฮ็กเวทที่จะทำให้งูใหญ่สามารถนำเข้าโมดูลหรือแพ็คเกจของคุณได้โดยไม่ต้องให้ผู้ใช้เพิ่มไดเรกทอรีที่มีไดเรกทอรีนั้นลงในพา ธ การนำเข้า" ดีแล้วที่รู้!
Jack O'Connor

1
สิ่งนี้ไม่ได้กล่าวถึงส่วนเอกสารสำคัญของโครงการที่จะวาง
lpapp

14
สับสนเกี่ยวกับ "ทำให้ซอร์สของคุณอยู่ในไดเร็กทอรีชื่อ src หรือ lib ซึ่งทำให้ยากต่อการรันโดยไม่ต้องติดตั้ง" จะติดตั้งอะไร? มันเป็นชื่อ dir ที่ทำให้เกิดปัญหาหรือความจริงที่ว่ามันเป็นส่วนย่อยหรือไม่?
Peter Ehrlich

4
"บางคนจะยืนยันว่าคุณควรกระจายการทดสอบภายในโมดูลของคุณ - ฉันไม่เห็นด้วยมันมักจะเพิ่มความซับซ้อนให้กับผู้ใช้ของคุณชุดทดสอบจำนวนมากมักต้องพึ่งพาเพิ่มเติมและบริบทรันไทม์" python-guide-pt-br.readthedocs.io/en/latest/writing/structure/…
endolith

2
"สิ่งนี้ทำให้ยากต่อการทำงานโดยไม่ต้องติดตั้ง" - นั่นเป็นประเด็น
Nick T

123

ตรวจสอบการเปิดโครงการจัดหาหลามทางขวา

ให้ฉันตัดตอนส่วนโครงงานของบทความที่ยอดเยี่ยมที่:

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

มาเริ่มกันที่จุดสูงสุด โครงการส่วนใหญ่มีไฟล์ระดับบนสุดจำนวนหนึ่ง (เช่น setup.py, README.md, requirements.txt และอื่น ๆ ) มีสามไดเรกทอรีที่ทุกโครงการควรมี:

  • ไดเรกทอรีเอกสารที่มีเอกสารโครงการ
  • ไดเรกทอรีชื่อด้วยชื่อของโครงการที่เก็บแพคเกจหลามจริง
  • ไดเรกทอรีทดสอบหนึ่งในสองแห่ง
    • ภายใต้ไดเรกทอรีแพคเกจประกอบด้วยรหัสทดสอบและทรัพยากร
    • ในฐานะไดเรกทอรีระดับบนสุดแบบสแตนด์อะโลนเพื่อให้เข้าใจวิธีการจัดระเบียบไฟล์ของคุณได้ดีขึ้นนี่เป็นภาพรวมที่เรียบง่ายของเค้าโครงสำหรับหนึ่งในโครงการของฉันแซนด์แมน:
$ pwd
~/code/sandman
$ tree
.
|- LICENSE
|- README.md
|- TODO.md
|- docs
|   |-- conf.py
|   |-- generated
|   |-- index.rst
|   |-- installation.rst
|   |-- modules.rst
|   |-- quickstart.rst
|   |-- sandman.rst
|- requirements.txt
|- sandman
|   |-- __init__.py
|   |-- exception.py
|   |-- model.py
|   |-- sandman.py
|   |-- test
|       |-- models.py
|       |-- test_sandman.py
|- setup.py

อย่างที่คุณเห็นมีไฟล์ระดับบนสุดคือไดเร็กทอรี docs (ที่สร้างขึ้นเป็นไดเร็กทอรีว่างที่สฟิงซ์จะใส่เอกสารที่สร้างขึ้น) ไดเรกทอรีแซนด์แมนและไดเรกทอรีทดสอบภายใต้แซนด์แมน


4
ฉันทำสิ่งนี้ แต่มากกว่านั้น: ฉันมี Makefile ระดับบนสุดที่มีเป้าหมาย 'env' ที่ทำให้ virtualenv env เป็นแบบอัตโนมัติ ./env/bin/pip install -r requirements.txt; ./env/bin/python setup.py พัฒนา 'และโดยปกติแล้วเป็นเป้าหมาย' ทดสอบ 'ที่ขึ้นอยู่กับ env และติดตั้งการทดสอบอ้างอิงแล้วเรียกใช้ py.test
pjz

@pjz คุณช่วยขยายความคิดของคุณได้ไหม? คุณกำลังพูดถึงการวางMakefileในระดับเดียวกับsetup.py? ดังนั้นถ้าฉันเข้าใจคุณอย่างถูกต้องmake envอัตโนมัติสร้างใหม่venvและติดตั้งแพคเกจลงในมัน ... ?
St.Antario

@ St.Antario อย่างแน่นอน ตามที่กล่าวไว้โดยทั่วไปแล้วฉันยังมีเป้าหมาย 'ทดสอบ' เพื่อเรียกใช้การทดสอบและบางครั้งเป้าหมาย 'ปล่อย' ที่ดูที่แท็กปัจจุบันและสร้างวงล้อและส่งไปยัง pypi
pjz

32

"Python Packaging Authority" มีตัวอย่างโครงการ:

https://github.com/pypa/sampleproject

เป็นโครงการตัวอย่างที่มีอยู่เพื่อช่วยในการสอนการใช้งาน Python Packaging Guide เกี่ยวกับบรรจุภัณฑ์และการกระจายโครงการ


+ แนวโน้มสู่root/src/*โครงสร้าง: github.com/pypa/sampleproject/commit/…
qrtLs

สำหรับโครงสร้างโครงการ recs ดูsetuptools.readthedocs.io/_/downloads/en/latest/pdf
qrtLs

19

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

  • คุณใส่แหล่งที่มาที่ไหน?

    • สำหรับโครงการขนาดใหญ่ที่เหมาะสมควรแยกแหล่งข้อมูลออกเป็นหลาย ๆ ฟอง PROJECT_ROOT/src/<egg_name>แต่ละไข่จะไปเป็นแยกต่างหากภายใต้ setuptools แบบการจัดวาง
  • คุณใส่สคริปต์เริ่มต้นแอปพลิเคชันไว้ที่ไหน

    • ตัวเลือกที่เหมาะสมที่สุดคือการลงทะเบียนสคริปต์เริ่มต้นแอปพลิเคชันว่าเป็นentry_pointหนึ่งในไข่
  • คุณใส่ cruft โครงการ IDE ที่ไหน

    • ขึ้นอยู่กับ IDE หลายคนเก็บสิ่งของไว้PROJECT_ROOT/.<something>ในรากของโครงการและนี่ก็ใช้ได้
  • คุณทำการทดสอบหน่วย / การตอบรับจากที่ไหน

    • ไข่แต่ละฟองมีชุดการทดสอบแยกต่างหากเก็บไว้ในPROJECT_ROOT/src/<egg_name>/testsไดเรกทอรี โดยส่วนตัวฉันชอบที่จะใช้py.testเพื่อเรียกใช้พวกเขา
  • คุณใส่ข้อมูลที่ไม่ได้อยู่ใน Python เช่นไฟล์ config ที่ไหน

    • มันขึ้นอยู่กับ. อาจมีข้อมูลที่ไม่ใช่ ธ ชนิดต่าง ๆ
      • "ทรัพยากร"คือข้อมูลที่ต้องบรรจุภายในไข่ ข้อมูลนี้จะเข้าสู่ไดเรกทอรีไข่ที่เกี่ยวข้องที่ไหนสักแห่งภายในเนมสเปซแพ็คเกจ สามารถใช้ผ่านpkg_resourcesแพ็คเกจจากsetuptoolsหรือตั้งแต่ Python 3.7 ผ่านimportlib.resourcesโมดูลจากไลบรารีมาตรฐาน
      • "Config-files"คือไฟล์ที่ไม่ใช่ Python ที่จะถือว่าเป็นไฟล์ภายนอกของโครงการ แต่จะต้องเริ่มต้นด้วยค่าบางค่าเมื่อแอปพลิเคชันเริ่มทำงาน ในระหว่างการพัฒนาฉันต้องการเก็บไฟล์ดังกล่าวPROJECT_ROOT/configไว้ สำหรับการปรับใช้อาจมีตัวเลือกต่าง ๆ บน Windows หนึ่งสามารถใช้%APP_DATA%/<app-name>/configบนลินุกซ์หรือ/etc/<app-name>/opt/<app-name>/config
      • ไฟล์ที่สร้างขึ้นเช่นไฟล์ที่อาจถูกสร้างหรือแก้ไขโดยแอปพลิเคชันระหว่างการดำเนินการ ฉันต้องการเก็บไว้ในPROJECT_ROOT/varระหว่างการพัฒนาและภายใต้/varระหว่างการปรับใช้ Linux
  • คุณใส่แหล่งข้อมูลที่ไม่ใช่ Python เช่น C ++ สำหรับโมดูลส่วนขยายไบนารี pyd / so ที่ไหน?
    • เข้าไป PROJECT_ROOT/src/<egg_name>/native

เอกสารมักจะเข้าไปPROJECT_ROOT/docหรือPROJECT_ROOT/src/<egg_name>/doc(ขึ้นอยู่กับว่าคุณพิจารณาว่าไข่บางส่วนเป็นโครงการขนาดใหญ่แยกต่างหาก) บางการกำหนดค่าเพิ่มเติมจะอยู่ในไฟล์เช่นและPROJECT_ROOT/buildout.cfgPROJECT_ROOT/setup.cfg


ขอบคุณสำหรับคำตอบที่ยอดเยี่ยม! คุณชี้แจงหลายสิ่งสำหรับฉัน! ฉันมีคำถามเดียว: ไข่ซ้อนกันได้ไหม
Shookie

ไม่คุณไม่สามารถ "ทำรัง" ไข่ในแง่ของการจัดเก็บไฟล์. egg ภายในไฟล์ .egg อื่น ๆ และหวังว่าสิ่งนี้จะมีประโยชน์อย่างมาก แต่สิ่งที่คุณสามารถทำได้คือสร้างไข่ "เสมือน" - แพ็คเกจเปล่าที่ไม่มีรหัสที่เป็นประโยชน์ แต่จะแสดงรายการแพ็คเกจอื่น ๆ ในรายการพึ่งพา ด้วยวิธีนี้เมื่อผู้ใช้พยายามติดตั้งแพคเกจดังกล่าวเขาจะติดตั้งไข่ซ้ำหลายครั้ง
KT

@KT คุณสามารถอธิบายเพิ่มเติมเล็กน้อยเกี่ยวกับวิธีจัดการข้อมูลที่สร้างขึ้นได้อย่างไร โดยเฉพาะอย่างยิ่งคุณ (ในรหัส) แยกแยะระหว่างการพัฒนาและการปรับใช้อย่างไร ฉันคิดว่าคุณมีbase_data_locationตัวแปรบ้างแต่คุณจะตั้งค่าได้อย่างไร?
cmyr

1
ฉันคิดว่าคุณกำลังพูดถึง "ข้อมูลรันไทม์" - สิ่งที่คนมักจะใส่ภายใต้ / var / packagename หรือ ~ / .packagename / var หรือ whatnot เวลาส่วนใหญ่ตัวเลือกเหล่านั้นเพียงพอเป็นค่าเริ่มต้นที่ผู้ใช้ของคุณไม่สนใจที่จะเปลี่ยนแปลง หากคุณต้องการอนุญาตให้ปรับพฤติกรรมนี้ได้ตัวเลือกค่อนข้างสมบูรณ์และฉันไม่คิดว่าจะมีวิธีปฏิบัติที่ดีที่สุดที่เหมาะสม ตัวเลือกทั่วไป: a) ~ / .packagename / configfile b) ส่งออก MY_PACKAGE_CONFIG = / path / to / configfile c) ตัวเลือกบรรทัดคำสั่งหรือพารามิเตอร์ฟังก์ชัน d) การรวมกันของสิ่งเหล่านั้น
KT

โปรดทราบว่าเป็นเรื่องปกติที่จะมีคลาสการกำหนดค่าแบบซิงเกิลตันซึ่งจัดการตรรกะการโหลดการตั้งค่าที่คุณชื่นชอบสำหรับคุณและอาจช่วยให้ผู้ใช้แก้ไขการตั้งค่าที่รันไทม์ โดยทั่วไปแล้วฉันคิดว่านี่เป็นปัญหาที่ควรค่ากับคำถามที่แยกต่างหาก
KT

15

จากประสบการณ์ของฉันมันเป็นเรื่องของการทำซ้ำ ใส่ข้อมูลและรหัสของคุณในทุกที่ที่คุณไป โอกาสที่คุณจะผิดอยู่ดี แต่เมื่อคุณได้รับความคิดที่ดีขึ้นว่าสิ่งที่รูปร่างจะขึ้นคุณจะอยู่ในตำแหน่งที่ดีขึ้นมากที่จะทำให้การคาดเดาเหล่านี้

เท่าที่เป็นส่วนขยายแหล่งที่มาเรามีไดเรกทอรีรหัสภายใต้ลำตัวที่มีไดเรกทอรีสำหรับหลามและไดเรกทอรีสำหรับภาษาอื่น ๆ โดยส่วนตัวแล้วฉันมีแนวโน้มที่จะลองวางรหัสส่วนขยายใด ๆ ลงในที่เก็บของตัวเองในครั้งต่อไป

ด้วยที่กล่าวว่าฉันกลับไปที่จุดเริ่มต้นของฉัน: อย่าทำเรื่องใหญ่เกินไป ใส่ไว้ในที่ที่เหมาะกับคุณ หากคุณพบสิ่งที่ไม่ได้ผลก็สามารถเปลี่ยน (และควร) ได้


อ๋อ ฉันพยายามที่จะ "Pythonic" เกี่ยวกับมัน: ชัดเจนดีกว่าโดยนัย .. ทายาทไดเรกทอรีจะอ่าน / ตรวจสอบมากกว่าที่พวกเขาเขียน ฯลฯ ..
eric

10

ข้อมูลที่ไม่ใช่งูหลามจะรวมที่ดีที่สุดภายในโมดูลหลามของคุณโดยใช้package_dataการสนับสนุนในการsetuptools สิ่งหนึ่งที่ผมขอแนะนำให้ใช้แพคเกจ namespace เพื่อสร้าง namespaces ที่ใช้ร่วมกันซึ่งหลายโครงการสามารถใช้ - เหมือนการประชุม Java ของการวางแพคเกจในcom.yourcompany.yourproject(และความสามารถที่จะมีการใช้ร่วมกันcom.yourcompany.utilsnamespace)

หากคุณใช้ระบบควบคุมแหล่งข้อมูลที่ดีพอมันจะจัดการการรวมแม้ผ่านการเปลี่ยนชื่อ บาซ่าเป็นอย่างดีในเรื่องนี้

ตรงข้ามกับคำตอบอื่น ๆ ที่นี่ฉัน +1 ที่มีsrcไดเรกทอรีระดับบนสุด (พร้อมdocและtestไดเรกทอรีข้าง) ข้อกำหนดเฉพาะสำหรับแผนผังไดเรกทอรีเอกสารจะแตกต่างกันไปขึ้นอยู่กับสิ่งที่คุณใช้ ตัวอย่างเช่นสฟิงซ์มีการประชุมเป็นของตัวเองซึ่งเครื่องมือ quickstart รองรับ

กรุณาใช้ประโยชน์จาก setuptools และ pkg_resources สิ่งนี้ทำให้ง่ายขึ้นสำหรับโครงการอื่น ๆ ที่จะต้องอาศัยเวอร์ชันที่เฉพาะเจาะจงของรหัสของคุณ (และสำหรับหลาย ๆ เวอร์ชันที่จะติดตั้งพร้อมกับไฟล์ที่ไม่ใช่รหัสที่แตกต่างกันหากคุณกำลังใช้งานpackage_data)

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