Làm thế nào để viết một mô-đun / gói Python?


375

Tôi đã tạo các kịch bản Python cho các tác vụ đơn giản tại nơi làm việc và không bao giờ thực sự bận tâm đóng gói chúng cho người khác sử dụng. Bây giờ tôi đã được chỉ định để tạo một trình bao bọc Python cho API REST. Tôi hoàn toàn không biết làm thế nào để bắt đầu và tôi cần sự giúp đỡ.

Tôi có gì:

(Chỉ muốn được cụ thể càng tốt) Tôi có virtualenv sẵn sàng, nó cũng lên github , file .gitignore cho trăn là có là tốt, cộng, các thư viện yêu cầu để tương tác với REST API. Đó là nó.

Đây là cây thư mục hiện tại

.
├── bin
   └── /the usual stuff/
├── include
   └── /the usual stuff/
├── lib
   └── python2.7
       └── /the usual stuff/
├── local
   └── /the usual stuff/
└── README.md

27 directories, 280 files

Tôi thậm chí không biết đặt các tệp .py ở đâu, nếu tôi đã từng tạo một tệp.

Những gì tôi muốn làm:

Tạo một mô-đun python có thể cài đặt với "pip install ..."

Nếu có thể, tôi muốn một quy trình từng bước chung để viết các mô-đun Python.


15
Tôi sẽ bắt đầu với chương 6 của hướng dẫn (2.7) hoặc ở đây cho 3.x Tìm kiếm hướng dẫn mô-đun python trên internet và bạn sẽ tìm thấy nhiều người khác.
Roland Smith

6
Không ai trả lời phần pip
whackamadoodle3000 17/07/17

github.com/MacHu-GWU/pygitrepo-project thư viện này giúp bạn tạo bộ xương dự án từ đầu, và tính năng bạn cần không có.
MacSanhe

Câu trả lời:


424

Một mô-đun là một tệp chứa các định nghĩa và câu lệnh Python. Tên tệp là tên mô-đun với hậu tố.py

tạo hello.pyrồi viết hàm sau như nội dung của nó:

def helloworld():
   print "hello"

Sau đó, bạn có thể nhập hello:

>>> import hello
>>> hello.helloworld()
'hello'
>>>

Để nhóm nhiều .pytập tin đặt chúng trong một thư mục. Bất kỳ thư mục có một __init__.pyđược coi là một mô-đun bởi python và bạn có thể gọi chúng là một gói

|-HelloModule
  |_ __init__.py
  |_ hellomodule.py

Bạn có thể thực hiện với câu lệnh nhập trên mô-đun của mình theo cách thông thường.

Để biết thêm thông tin, xem 6.4. Gói .


7
cái cuối cùng sẽ là: từ HellowModule nhập hellomodule? Có thể đó là lời chào trong thư mục mô-đun, vì vậy nó sẽ là từ nhập HelloModule xin chào
nycynik

Hiện đang chơi xung quanh với Python và câu trả lời này phải là một trong những điều hữu ích nhất mà tôi gặp. Giải thích nó rất tốt, cảm ơn bạn.
Darren Wainwright

lệnh "pip install" sẽ không hoạt động, ngoài ra bạn phải ở trong cùng thư mục để sử dụng nó
Math Coder 101

234

Python 3 - CẬP NHẬT ngày 18 tháng 11 năm 2015

Tìm thấy câu trả lời được chấp nhận hữu ích, nhưng muốn mở rộng trên một số điểm vì lợi ích của người khác dựa trên kinh nghiệm của riêng tôi.

Mô-đun: Mô-đun là một tệp chứa các định nghĩa và câu lệnh Python. Tên tệp là tên mô-đun có hậu tố .py được nối thêm.

Ví dụ mô-đun : Giả sử chúng ta có một tập lệnh python duy nhất trong thư mục hiện tại, ở đây tôi gọi nó là mymodule.py

Tệp mymodule.py chứa mã sau đây:

def myfunc():
    print("Hello!")

Nếu chúng tôi chạy trình thông dịch python3 từ thư mục hiện tại, chúng tôi có thể nhập và chạy hàm myfunc theo các cách khác nhau sau (bạn thường chỉ cần chọn một trong các cách sau):

>>> import mymodule
>>> mymodule.myfunc()
Hello!
>>> from mymodule import myfunc
>>> myfunc()
Hello!
>>> from mymodule import *
>>> myfunc()
Hello!

Ok, vậy là đủ dễ dàng.

Bây giờ giả sử bạn có nhu cầu đặt mô-đun này vào thư mục chuyên dụng của riêng nó để cung cấp một không gian tên mô-đun, thay vì chỉ chạy nó ad-hoc từ thư mục làm việc hiện tại. Đây là nơi đáng để giải thích khái niệm về một gói .

Gói : Các gói là một cách cấu trúc không gian tên mô-đun của Python bằng cách sử dụng các tên mô-đun rải rác của Wap. Ví dụ, tên mô-đun AB chỉ định một mô hình con có tên B trong gói có tên A. Giống như việc sử dụng các mô-đun giúp các tác giả của các mô-đun khác nhau không phải lo lắng về tên biến toàn cục của nhau, việc sử dụng tên mô-đun chấm chấm sẽ cứu các tác giả của các gói đa mô-đun như NumPy hoặc Thư viện hình ảnh Python không phải lo lắng về tên mô-đun của nhau.

Ví dụ gói : Bây giờ giả sử chúng ta có các thư mục và tệp sau. Ở đây, mymodule.py giống hệt với trước đây và __init__.py là một tệp trống:

.
└── mypackage
    ├── __init__.py
    └── mymodule.py

Các tệp __init__.py được yêu cầu để làm cho Python coi các thư mục là các gói chứa. Để biết thêm thông tin, xin vui lòng xem liên kết tài liệu Mô-đun được cung cấp sau này.

Thư mục làm việc hiện tại của chúng tôi là một cấp trên thư mục thông thường được gọi là mypackage

$ ls
mypackage

Nếu chúng ta chạy trình thông dịch python3 ngay bây giờ, chúng ta có thể nhập và chạy mô-đun mymodule.py chứa hàm yêu cầu myfunc theo các cách khác nhau (bạn thường chỉ cần chọn một trong các cách sau):

>>> import mypackage
>>> from mypackage import mymodule
>>> mymodule.myfunc()
Hello!
>>> import mypackage.mymodule
>>> mypackage.mymodule.myfunc()
Hello!
>>> from mypackage import mymodule
>>> mymodule.myfunc()
Hello!
>>> from mypackage.mymodule import myfunc
>>> myfunc()
Hello!
>>> from mypackage.mymodule import *
>>> myfunc()
Hello!

Giả sử Python 3, có tài liệu tuyệt vời tại: Mô-đun

Về các quy ước đặt tên cho các gói và mô-đun, các hướng dẫn chung được đưa ra trong PEP-0008 - vui lòng xem Tên gói và Tên mô-đun

Các mô-đun nên có tên ngắn, tất cả chữ thường. Dấu gạch dưới có thể được sử dụng trong tên mô-đun nếu nó cải thiện khả năng đọc. Các gói Python cũng nên có tên viết tắt, tất cả chữ thường, mặc dù việc sử dụng dấu gạch dưới không được khuyến khích.


5
Giải thích đơn giản. Điều gì nếu bạn muốn giữ một thư mục khác trong mypackage?
Anuj Gupta

3
Bao gồm hoàn toàn phụ thuộc vào những gì bạn đã viết. Trong trường hợp bạn đặt công cụ bên ngoài một chức năng trên mô-đun của mình, bạn sẽ kích hoạt nó khi gọi như thế import mypackage. Trong trường hợp bạn muốn nhập chỉ một chức năng từ một mô-đun (thậm chí là một tệp) thì tốt hơn để sử dụng from module import function. Trong trường hợp một thư mục con from subfolder.module import functionđể bạn có thể gọi function()witthout fire các phần mã khác. Ngoài ra, không sử dụng from module import *nếu bạn không thực sự cần.
m3nda

5
Câu hỏi duy nhất còn lại là làm thế nào tôi có thể nhận được gói để nhập mọi thứ trên import mypackage? Thêm import mymodulevào __init__.pykhông hoạt động ..
576i

Giải thích gọn gàng! tuy nhiên, tôi có một câu hỏi nếu numpy là một gói làm thế nào tôi có thể thực thi numpy.cos (1) trong trình thông dịch của mình bởi vì đó dường như là một tên mô-đun ở giữa bị mất. Không?
dùng1935724

3
Làm thế nào về pip?
whackamadoodle3000

199

Vì chưa có ai trả lời câu hỏi này của OP:

Những gì tôi muốn làm:

Tạo một mô-đun python có thể cài đặt với "pip install ..."

Dưới đây là một ví dụ tối thiểu tuyệt đối, hiển thị các bước cơ bản để chuẩn bị và tải gói của bạn lên PyPI bằng cách sử dụng setuptoolstwine.

Đây không phải là một sự thay thế cho việc đọc ít nhất là hướng dẫn , có nhiều thứ hơn là được trình bày trong ví dụ rất cơ bản này.

Việc tạo gói chính nó đã được bao phủ bởi các câu trả lời khác ở đây, vì vậy chúng ta hãy giả sử rằng chúng ta có bước đó được bảo hiểm và cấu trúc dự án của chúng ta như thế này:

.
└── hellostackoverflow/
    ├── __init__.py
    └── hellostackoverflow.py

Để sử dụng setuptoolscho việc đóng gói, chúng tôi cần thêm một tệp setup.py, điều này đi vào thư mục gốc của dự án của chúng tôi:

.
├── setup.py
└── hellostackoverflow/
    ├── __init__.py
    └── hellostackoverflow.py

Tối thiểu, chúng tôi chỉ định siêu dữ liệu cho gói của chúng tôi, chúng tôi setup.pysẽ trông như thế này:

from setuptools import setup

setup(
    name='hellostackoverflow',
    version='0.0.1',
    description='a pip-installable package example',
    license='MIT',
    packages=['hellostackoverflow'],
    author='Benjamin Gerfelder',
    author_email='benjamin.gerfelder@gmail.com',
    keywords=['example'],
    url='https://github.com/bgse/hellostackoverflow'
)

Vì chúng tôi đã thiết lập license='MIT', chúng tôi bao gồm một bản sao trong dự án của chúng tôi LICENCE.txt, cùng với tệp readme trong reSturationuredText như README.rst:

.
├── LICENCE.txt
├── README.rst
├── setup.py
└── hellostackoverflow/
    ├── __init__.py
    └── hellostackoverflow.py

Tại thời điểm này, chúng tôi đã sẵn sàng để bắt đầu sử dụng bao bì setuptools, nếu chúng tôi chưa cài đặt nó, chúng tôi có thể cài đặt nó với pip:

pip install setuptools

Để làm điều đó và tạo một source distribution, tại thư mục gốc dự án của chúng tôi, chúng tôi gọi chúng tôi setup.pytừ dòng lệnh, chỉ định chúng tôi muốn sdist:

python setup.py sdist

Điều này sẽ tạo gói phân phối và thông tin trứng của chúng tôi và dẫn đến cấu trúc thư mục như thế này, với gói của chúng tôi trong dist:

.
├── dist/
├── hellostackoverflow.egg-info/
├── LICENCE.txt
├── README.rst
├── setup.py
└── hellostackoverflow/
    ├── __init__.py
    └── hellostackoverflow.py

Tại thời điểm này, chúng tôi có một gói chúng tôi có thể cài đặt bằng cách sử dụng pip, do đó, từ gốc dự án của chúng tôi (giả sử bạn có tất cả các cách đặt tên như trong ví dụ này):

pip install ./dist/hellostackoverflow-0.0.1.tar.gz

Nếu mọi việc suôn sẻ, bây giờ chúng ta có thể mở trình thông dịch Python, tôi sẽ nói ở đâu đó bên ngoài thư mục dự án của chúng tôi để tránh mọi sự nhầm lẫn và cố gắng sử dụng gói mới sáng bóng của chúng tôi:

Python 3.5.2 (default, Sep 14 2017, 22:51:06) 
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from hellostackoverflow import hellostackoverflow
>>> hellostackoverflow.greeting()
'Hello Stack Overflow!'

Bây giờ chúng tôi đã xác nhận gói cài đặt và hoạt động, chúng tôi có thể tải nó lên PyPI.

Vì chúng tôi không muốn làm ô nhiễm kho lưu trữ trực tiếp bằng các thử nghiệm của mình, chúng tôi tạo một tài khoản cho kho lưu trữ thử nghiệm và cài đặt twinecho quá trình tải lên:

pip install twine

Bây giờ chúng tôi gần như ở đó, với tài khoản của chúng tôi được tạo, chúng tôi chỉ cần twineyêu cầu tải lên gói của chúng tôi, nó sẽ yêu cầu thông tin đăng nhập của chúng tôi và tải gói của chúng tôi lên kho lưu trữ được chỉ định:

twine upload --repository-url https://test.pypi.org/legacy/ dist/*

Bây giờ chúng tôi có thể đăng nhập vào tài khoản của mình trên kho lưu trữ kiểm tra PyPI và ngạc nhiên với gói mới tải lên của chúng tôi trong một thời gian, sau đó lấy nó bằng cách sử dụng pip:

pip install --index-url https://test.pypi.org/simple/ hellostackoverflow

Như chúng ta có thể thấy, quá trình cơ bản không phức tạp lắm. Như tôi đã nói trước đó, có rất nhiều điều hơn là được đề cập ở đây, vì vậy hãy tiếp tục và đọc hướng dẫn để được giải thích sâu hơn.


Gói của tôi sẽ được công bố ngay sau đó setuptools?
U10-Chuyển tiếp

@ U9-Chuyển tiếp Không, việc xuất bản được thực hiện với twine, nhưng bạn có thể kiểm tra gói của mình cục bộ trước khi xuất bản sau khi bạn tạo nó với setuptools.
bgse

9

Khi bạn đã xác định các lệnh đã chọn, bạn chỉ cần kéo và thả tệp đã lưu vào thư mục Lib trong tệp chương trình python của bạn.

>>> import mymodule 
>>> mymodule.myfunc()

2

Tạo một tệp có tên là "hello.py"

Nếu bạn đang sử dụng Python 2.x

def func():
    print "Hello"

Nếu bạn đang sử dụng Python 3.x

def func():
    print("Hello")

Chạy tập tin. Sau đó, bạn có thể thử như sau:

>>> import hello
>>> hello.func()
Hello

Nếu bạn muốn một chút khó khăn, bạn có thể sử dụng như sau:

Nếu bạn đang sử dụng Python 2.x

def say(text):
    print text

Nếu bạn đang sử dụng Python 3.x

def say(text):
    print(text)

Xem một trong ngoặc đơn bên cạnh định nghĩa? Đó là điều quan trọng. Đây là một trong những bạn có thể sử dụng trong định nghĩa.

Văn bản - Bạn có thể sử dụng nó khi bạn muốn chương trình nói những gì bạn muốn. Theo tên của nó, nó là văn bản. Tôi hy vọng bạn biết văn bản có nghĩa là gì. Nó có nghĩa là "từ" hoặc "câu".

Chạy tập tin. Sau đó, bạn có thể thử các cách sau nếu bạn đang sử dụng Python 3.x:

>>> import hello
>>> hello.say("hi")
hi
>>> from hello import say
>>> say("test")
test

Đối với Python 2.x - Tôi đoán điều tương tự với Python 3? Không ý kiến. Sửa lỗi cho tôi nếu tôi mắc lỗi trên Python 2.x (Tôi biết Python 2 nhưng tôi đang sử dụng với Python 3)


2

Tôi đã tạo một dự án để dễ dàng bắt đầu một bộ xương dự án từ đầu . https://github.com/MacHu-GWU/pygitrepo-project .

Và bạn có thể tạo một dự án thử nghiệm, giả sử , learn_creating_py_package.

Bạn có thể tìm hiểu thành phần nào bạn nên có cho các mục đích khác nhau như :

  • tạo virtualenv
  • tự cài đặt
  • chạy chậm nhất
  • chạy bảo hiểm mã
  • xây dựng tài liệu
  • triển khai tài liệu
  • chạy unittest trong phiên bản python khác nhau
  • triển khai lên PYPI

Ưu điểm của việc sử dụng pygitrepolà những tẻ nhạt sẽ được tự động tạo ra chính nó và thích ứng của bạn package_name, project_name, github_account, document host service, windows or macos or linux.

Đó là một nơi tốt để học phát triển một dự án python như một pro.

Hy vọng điều này có thể giúp đỡ.

Cảm ơn bạn.

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.