2013-07-03 34 views
14

Tôi là người mới sử dụng gói quản lý python, và chắc chắn đã làm điều gì sai. Tôi đã khuyến khích để tạo ra một cấu trúc thư mục như sau:Cách cấu trúc các gói python mà không lặp lại tên cấp cao nhất để nhập

bagoftricks 
├── bagoftricks 
│   ├── bagoftricks 
│   │   ├── __init__.py 
│   │   └── bagoftricks.py 
│   └── __init__.py 
├── README.md 
└── setup.py 

bagoftricks.py chứa hai chức năng, levenshtein()geofind().

Tôi muốn gọi những as:

import bagoftricks 

x = bagoftricks.levenshtein(arg1,arg2) 

Thay vào đó, tôi thấy tôi phải làm điều này:

import bagoftricks 

x = bagoftricks.bagoftricks.levenshtein(arg1,arg2) 

Có cách nào tốt hơn để tổ chức gói của tôi ở nơi đầu tiên, mà không có sự dư thừa đặt tên?

CẬP NHẬT

Vì vậy, tôi làm theo hướng dẫn Avichal Badaya của dưới đây, và loại bỏ một mức độ làm tổ. Đó là, bây giờ tôi phải ...

bagoftricks 
├── bagoftricks 
│   ├── __init__.py 
│   └── bagoftricks.py 
├── README.md 
└── setup.py 

Tuy nhiên, để gọi gói này, tôi vẫn còn có ...

from bagoftricks.bagoftricks import geofind() 

hoặc

import bagoftricks 

sau đó

>>> bagoftricks.bagoftricks.geofind() 

Thay vì mong muốn ....

from bagoftricks import geofind() 

hoặc

import bagoftricks 

>>> bagoftricks.geofind() 

tôi không thể loại bỏ thêm rằng lớp làm tổ. Khi tôi cố gắng, bằng cách tương tự, để loại bỏ một mức độ làm tổ, do đó mô-đun của tôi là bằng phẳng, như:

bagoftricks 
├── __init__.py 
├── bagoftricks.py 
├── README.md 
└── setup.py 

tôi không thể xây dựng các gói ở tất cả ...

$ python setup.py build 
running build 
running build_py 
error: package directory 'bagoftricks' does not exist 

gì là bí mật cho nhập khẩu tự nhiên như gói tiêu chuẩn sử dụng, không cần nhập khẩu tên cấp cao?

Trả lời

20

Cấp độ đầu tiên "bagoftricks" là tốt. Đó chỉ là tên của "dự án" của bạn để nói chuyện. Trong đó bạn có một setup.py và các tệp khác cho biết hệ thống đóng gói những gì họ cần biết.

Sau đó, bạn có thể có mã trực tiếp trong mô-đun này hoặc trong thư mục src. Bạn thậm chí có thể đi xa như chỉ có cấu trúc này:

bagoftricks 
├── bagoftricks.py 
├── README.md 
└── setup.py 

Nhưng tôi sẽ không khuyên, chủ yếu là bởi vì bạn có thể muốn sắp xếp lại mọi thứ sau đó, và nó dễ dàng hơn nếu bạn đã có một gói phần mềm "phù hợp". Ngoài ra hầu hết mọi người, công cụ và tài liệu giả sử bạn có một gói, vì vậy nó dễ dàng hơn.

Vì vậy, tối thiểu sẽ là:

bagoftricks 
├── bagoftricks 
│ └── __init__.py 
├── README.md 
└── setup.py 

Với __init__.py chứa các chức năng bạn muốn nhập. Sau đó bạn sử dụng các chức năng như thế này:

from bagoftricks import levenshtein, anotherfunction 

Khi đã __init__.py trở nên quá lớn, bạn muốn chia nó lên trong một số mô-đun, đem lại cho bạn một cái gì đó như thế này:

bagoftricks 
├── bagoftricks 
│ ├── __init__.py 
│ ├── anothermodule.py 
│ └── levenshtein.py 
├── README.md 
└── setup.py 

bạn __init__.py nên sau đó nhập khẩu các chức năng từ các mô-đun khác nhau:

from bagoftricks.levenshtein import levenshtein 
from bagoftricks.anothermodule import anotherfunction 

Và sau đó bạn vẫn có thể sử dụng chúng như bạn đã làm trước đây.

+0

Cảm ơn, điều đó rõ ràng và hữu ích, đặc biệt là mẹo về cách phát triển nó một cách hiệu quả và đúng đắn. Vấn đề chắc chắn là tuyên bố __init__.py của tôi sau đó. Tôi không hoàn toàn hiểu nơi nó ngồi trong hệ thống phân cấp và nơi để đặt nó để rút ngắn cuộc gọi. Hoạt động hoàn hảo. Cảm ơn! – Mittenchops

1

Thực hiện theo cấu trúc sau:

bagoftricks 
    ── bagoftricks 
    │ ├── __init__.py 
    │ └── bagoftricks.py 
    ├── README.md 
    └── setup.py 

và sau đó bạn sẽ có thể sử dụng nó như:

from bagoftricks.bagoftricks import levenshtein, geofind 

nhưng sau khi bạn thực hiện thay đổi trong cấu trúc thư mục làm: -

pip uninstall <your package name mostly mentioned in setup.py> 

và cài đặt lại gói

trong khi đó hãy kiểm tra thiết lập của bạn.py

#!/bin/env python 
import os.path 
from setuptools import setup, find_packages 

def current_path(file_name): 
    return os.abspath(os.path.join(__file__, os.path.pardir, file_name)) 

setup(
    name = 'bagoftricks', 
    version = '0.1', 
    include_package_data = True, 
    packages=find_packages(), 
) 

thiết lập cũng có thể có một số thông số khác. Tôi hy vọng nó làm việc cho bạn.

+0

Is có bất kỳ cấu hình nào có thể cho phép tôi thực hiện nó bằng một cuộc gọi không? Chỉ cần 'từ bagoftricks nhập khẩu levenshtein, geofind' thay vì gọi submodule,' từ bagoftricks.bagoftricks nhập khẩu levenshtein, geofind'? – Mittenchops

+0

@Mittenchops đặt 'từ. bagoftricks nhập khẩu levenshtein, geofind' trong 'bagoftricks/__ init __. py' – amigcamel

1

với cấu trúc được cập nhật bạn đăng

bagoftricks 
├── bagoftricks 
│ ├── __init__.py 
│ └── bagoftricks.py 
├── README.md 
└── setup.py 

into bagoftricks/__init__.py import all functions that you need 

__init__.py 
from bagoftricks import geofind, levenshtein 

vào một chương trình khác nhau mà bạn có thể làm các follwing

from bagoftricks import geofind 
import bagoftricks; bagoftricks.geofind(); bagoftricks.bagoftriks.geofind() 

lưu ý rằng bạn có thể nhập cũng một thẻ hoang dã

from bagoftricks import * 
+0

Mặc dù nhập khẩu các ký tự đại diện như 'từ nhập khẩu mô-đun * 'được coi là thực hành rất xấu, bởi vì nó có thể gây xung đột không gian tên. Luôn cố gắng nhập bằng cách đặt tên cho mọi thứ bạn nhập. – kramer65

+0

có - bạn là đúng nhưng đối với ví dụ này là tốt - cũng lưu ý rằng các mô-đun từ bagoftricks được nhập khẩu vào không gian tên bagoftricks. – silviud

+0

Chỉ cần tự hỏi; tại sao nó lại tốt cho ví dụ này? Nếu bạn nhập geofind từ bagoftricks sau đó bạn nhập một hàm cũng được gọi là geofind từ một mô-đun khác, bạn đã có một xung đột. Tôi đang thiếu gì ở đây? Tại sao ví dụ này khác với mã Python khác? Nhập bằng ký tự đại diện là thực hành không đúng, thời gian. – kramer65

Các vấn đề liên quan