Làm thế nào để tổ chức một Dự án Python?


76

Tôi mới làm quen với Python và tôi đang bắt đầu một Dự án nhỏ, nhưng tôi có một số nghi ngờ về cách tổ chức các thư mục trong "Python Way".

Tôi đang sử dụng PyDevtrong Môi trường phát triển của mình và khi tôi tạo một dự án mới, một thư mục được tạo có tênsrc

+ src

Bây giờ, trong PyDev, tôi có thể tạo Pydev ModulePyDev Package

Tôi cần tổ chức Dự án của mình theo cách sau:

+ Indicators
    - Moving_averages.py
    - Stochastics.py
+ Strategies
    - Moving_averages_cross.py
- example.py

Làm cách nào để tổ chức việc này theo Mô-đun và Gói? Ý nghĩa của Mô-đun và Gói là gì?

Trân trọng,


1
Tôi có thể giới thiệu liên kết này , từ Hướng dẫn Python chính thức . Nó có khá nhiều rõ ràng và thẳng về phía trước.
LiorK

Một bài đăng rất hữu ích gần đây: Bắt đầu một dự án python đúng cách
karlcow

Câu trả lời:


49

Về cơ bản, Gói là một thư mục chứa __init__.pytệp bên dưới nó và thường là một số Mô-đun, trong đó Mô-đun là một *.pytệp. Nó liên quan đếnimport chủ yếu. Nếu bạn thêm __init__.pyvào Chỉ báo, bạn có thể sử dụng:

from Indicators.Stochastics import *

hoặc là

from Indicators import Stochastics

Nhân tiện, tôi khuyên bạn nên giữ tên mô-đun / gói là chữ thường. Nó không ảnh hưởng đến chức năng nhưng nó "pythonic" hơn.


40

Từ quan điểm hệ thống tệp, một mô-đun là một tệp kết thúc bằng .pyvà một gói là một thư mục chứa các mô-đun và các gói (lồng nhau) lại. Python nhận dạng một thư mục là một gói nếu nó chứa một __init__.pytệp.

Một cấu trúc tệp như vậy

some/
    __init__.py
    foofoo.py
    thing/
        __init__.py
        barbar.py

xác định gói some, trong đó có một mô-đun foofoovà một gói lồng nhau thing, lại có một mô-đun barbar. Tuy nhiên, khi sử dụng các gói và mô-đun, bạn không thực sự phân biệt được hai loại này:

import some

some.dothis() # dothis is defined in 'some/__init__.py'

import some.foofoo # <- module
import some.thing # <- package

Vui lòng làm theo PEP8 khi chọn đặt tên cho các gói / mô-đun của bạn (tức là sử dụng tên viết thường).


2
Tôi có thể gọi hàm từ foofoo.pynếu tôi chỉ nhập một số không? Tôi bối rối về __init__.py, những gì tôi nên đặt ở đó?
Jay Wong

27

Xem python-package-template

Cấu trúc thư mục

    .
    |-- bin
    |   `-- my_program
    |-- docs
    |   `-- doc.txt
    |-- my_program
    |   |-- data
    |   |   `-- some_data.html
    |   |-- __init__.py
    |   |-- submodule
    |   |   `-- __init__.py
    |   |-- helpers.py
    |-- tests
    |   |-- __init__.py
    |   |-- test_helpers.py
    |-- Makefile
    |-- CHANGES.txt
    |-- LICENSE.txt
    |-- README.md
    |-- requirements-dev.txt
    |-- requirements.txt
    `-- setup.py

mèo Makefile

    PYTHON=`which python`
    NAME=`python setup.py --name`


    all: check test source deb

    init:
        pip install -r requirements.txt --use-mirrors

    dist: source deb

    source:
        $(PYTHON) setup.py sdist

    deb:
        $(PYTHON) setup.py --command-packages=stdeb.command bdist_deb

    rpm:
        $(PYTHON) setup.py bdist_rpm --post-install=rpm/postinstall --pre-uninstall=rpm/preuninstall

    test:
        unit2 discover -s tests -t .
        python -mpytest weasyprint

    check:
        find . -name \*.py | grep -v "^test_" | xargs pylint --errors-only --reports=n
        # pep8
        # pyntch
        # pyflakes
        # pychecker
        # pymetrics

    clean:
        $(PYTHON) setup.py clean
        rm -rf build/ MANIFEST dist build my_program.egg-info deb_dist
        find . -name '*.pyc' -delete

2
chào, Vitaly! Tôi vừa xem qua dự án của bạn. Bạn vẫn đang duy trì nó? Cảm ơn!
Elias Dorneles

2
Đã kết thúc với một 404
Dimitrios Mistriotis

2
Liên kết https://github.com/vital-fadeev/python-package-templatekhông còn hợp lệ. Có thể tìm thấy mẫu python-package-này ở đâu?
Toothpick Anemone

14

Bạn có thể muốn xem thư viện mẫu gói-hiện đại. Nó cung cấp một cách để thiết lập một bố cục cơ bản thực sự đẹp cho một dự án hướng dẫn bạn qua một số câu hỏi và cố gắng giúp bạn có được thứ gì đó có thể được phân phối khá dễ dàng.

http://pypi.python.org/pypi/modern-package-template


8

Trước khi quyết định cấu trúc dự án, bạn nên tự hỏi bản thân xem mục đích của dự án sẽ là gì. Đây có phải là một phân tích duy nhất không? Một khái niệm đồ chơi bạn muốn điều tra? Một dự án đầy đủ mà bạn định phân phối? Số lượng nỗ lực bạn muốn bỏ ra để cấu trúc dự án của mình sẽ khác nhau.

  • Nếu đó là một phân tích riêng lẻ, tôi thích sử dụng máy tính xách tay ipython . Sổ ghi chép sẽ ghi lại dòng suy nghĩ của bạn và bạn có thể thêm ghi chú trong đánh dấu vào mã của mình để tham khảo sau này.
  • Nếu đó là một khái niệm đồ chơi mà bạn muốn điều tra, tôi thấy một cách tiếp cận đơn giản, nhanh chóng để hoạt động tốt nhất. Bạn muốn có thể nhanh chóng triển khai khái niệm của mình để khám phá xem liệu nó có khả thi hay không và do đó đáng để dành nhiều thời gian hơn cho nó. Một phần triết lý của Python là 'Đừng cố gắng hoàn hảo bởi vì "đủ tốt" thường chỉ có vậy. " Bạn luôn có thể quay lại sau và cấu trúc dự án của mình theo cách tuân theo các phương pháp kỹ thuật phần mềm tốt nhất.
  • Nếu bạn muốn cấu trúc dự án của mình để sau này bạn có thể phân phối nó và để nó mở rộng thành nhiều mô-đun, tôi khuyên bạn nên cấu trúc sau:

    projectname
     ├── MANIFEST.in
     ├── setup.py
     ├── README
     ├── .gitignore
     ├── .git
     ├── projectname_env
     └── projectname
         ├── __init__.py
         ├── subpackageone
         │   ├── __init__.py
         │   ├── second_module.py
         │   ├── tests
         │   │   └── test_second_module.py
         │   └── models
         │       └── model1
         ├── first_module.py   
         └── tests
             └── test_second_module.py
    

Lý do chi tiết tại sao tôi thích cấu trúc này có trong bài đăng trên blog của tôi , nhưng ý chính cơ bản là thư mục cấp thấp hơn được phân cấp projectnamechứa dự án thực tế của bạn. Bên cạnh đó là tất cả các công cụ giúp quản lý (git) và đóng gói (setup.py, MANIFEST.in) nó.


Bạn sẽ chạy dự án của mình như thế nào? Trong thư mục gốc làm gì python3 -m projectname?
buhtz

4

Một gói là một thư mục có __init__.py trong đó. Sự khác biệt so với một thư mục là bạn có thể nhập nó.

Không có "cách Python" nào cả, nhưng bạn sẽ thấy rằng nên đặt tất cả các mô-đun của mình trong một gói có tên liên quan đến dự án.

Ngoài ra, để làm theo hướng dẫn kiểu Python, PEP8, tên gói và mô-đun phải là chữ thường. Vì vậy, nếu chúng tôi giả sử dự án được gọi là "Thống kê Botond" thì cấu trúc của bạn sẽ như thế này:

botondstats/
    indicators/
        moving_averages.py
        stochastics.py
    strategies/
        moving_averages_cross.py
    example.py

Sau đó, bạn sẽ tìm thấy lớp Stochastics bằng cách

from botondstats.indicators.stochastics.Stochastics

(Có nhiều cách khác nhau để giữ cấu trúc nhưng làm cho việc nhập khẩu ngắn hơn, nhưng đó là một câu hỏi khác).

Bạn có thể đặt cấu trúc này src/nếu muốn nhưng không cần thiết. Tôi chưa bao giờ làm. Thay vào đó, tôi có một thư mục chính:

BotondStatistics/
    docs/
    botonstats/ # the above structure
    setup.py    # Distutils/distribute configuration for packaging.

Trong thư mục này, tôi cũng thường có một virtualenv vì vậy tôi thực sự cũng có bin / lib / et al. Phát triển thường được thực hiện bằng cách chạy

./bin/python setup.py tests

Khi tôi sử dụng trình chạy thử nghiệm Distrubute để chạy thử nghiệm.

Đó là cách tôi làm. :-)



Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.