Bagaimana cara menulis modul / paket Python?

375

Saya telah membuat skrip Python untuk tugas-tugas sederhana di tempat kerja dan tidak pernah repot-repot mengemasnya untuk digunakan orang lain. Sekarang saya telah ditugaskan untuk membuat pembungkus Python untuk API REST. Saya sama sekali tidak tahu bagaimana memulai dan saya butuh bantuan.

Apa yang saya punya:

(Hanya ingin sespesifik mungkin) Saya sudah siapkan virtualenv , itu juga di github , file .gitignore untuk python juga ada, ditambah, perpustakaan permintaan untuk berinteraksi dengan REST API. Itu dia.

Berikut pohon direktori saat ini

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

27 directories, 280 files

Saya bahkan tidak tahu di mana harus meletakkan file .py, jika saya pernah membuatnya.

Apa yang ingin saya lakukan:

Buat modul python dapat diinstal dengan "pip install ..."

Jika memungkinkan, saya ingin proses langkah demi langkah umum dalam menulis modul Python.

yowmamasita
sumber
15
Saya akan mulai dengan bab 6 dari tutorial (2.7) , atau di sini untuk 3.x Cari di internet untuk tutorial modul python dan Anda akan menemukan banyak lainnya.
Roland Smith
6
Tidak ada yang menjawab bagian pip
whackamadoodle3000
github.com/MacHu-GWU/pygitrepo-project perpustakaan ini membantu Anda untuk membuat kerangka proyek dari awal, dan fitur yang Anda butuhkan di luar kotak.
MacSanhe

Jawaban:

424

Modul adalah file yang berisi definisi dan pernyataan Python. Nama file adalah nama modul dengan akhiran.py

buat hello.pylalu tulis fungsi berikut sebagai isinya:

def helloworld():
   print "hello"

Kemudian Anda dapat mengimpor hello:

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

Untuk mengelompokkan banyak .pyfile, masukkan ke dalam folder. Folder apa pun dengan __init__.pydianggap sebagai modul oleh python dan Anda dapat memanggil mereka sebuah paket

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

Anda dapat melanjutkan dengan pernyataan impor pada modul Anda dengan cara biasa.

Untuk informasi lebih lanjut, lihat 6.4. Paket .

Anuj
sumber
7
apakah yang terakhir adalah: dari impor HellowModule hellomodule? Mungkinkah itu halo dalam folder modul, jadi itu akan dari HelloModule import hello
nycynik
Saat ini bermain-main dengan Python dan jawaban ini harus menjadi salah satu yang paling membantu yang pernah saya temui. Jelaskan dengan sangat baik, terima kasih.
Darren Wainwright
perintah "pip install" tidak akan berfungsi, Anda juga harus berada di direktori yang sama untuk menggunakannya
Math Coder 101
234

Python 3 - DIPERBARUI 18 November 2015

Menemukan jawaban yang diterima bermanfaat, namun ingin memperluas beberapa poin untuk kepentingan orang lain berdasarkan pengalaman saya sendiri.

Modul: Modul adalah file yang berisi definisi dan pernyataan Python. Nama file adalah nama modul dengan akhiran .py ditambahkan.

Modul Contoh : Asumsikan kita memiliki skrip python tunggal dalam direktori saat ini, di sini saya menyebutnya mymodule.py

File mymodule.py berisi kode berikut:

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

Jika kita menjalankan interpreter python3 dari direktori saat ini, kita dapat mengimpor dan menjalankan fungsi myfunc dengan cara-cara berbeda berikut (Anda biasanya hanya memilih salah satu dari yang berikut):

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

Ok, jadi itu cukup mudah.

Sekarang anggap Anda memiliki kebutuhan untuk meletakkan modul ini ke folder khusus untuk menyediakan ruang nama modul, bukan hanya menjalankannya ad-hoc dari direktori kerja saat ini. Di sinilah ada baiknya menjelaskan konsep suatu paket .

Paket : Paket adalah cara penataan namespace modul Python dengan menggunakan "dotted module names". Sebagai contoh, nama modul AB menunjuk sebuah submodule bernama B dalam paket bernama A. Sama seperti penggunaan modul menyelamatkan penulis modul yang berbeda dari harus khawatir tentang nama variabel global masing-masing, penggunaan nama modul bertitik menyimpan penulis paket multi-modul seperti NumPy atau Python Imaging Library karena harus khawatir tentang nama modul masing-masing.

Paket Contoh : Sekarang mari kita asumsikan kita memiliki folder dan file berikut. Di sini, mymodule.py identik dengan sebelumnya, dan __init__.py adalah file kosong:

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

File __init__.py diperlukan untuk membuat Python memperlakukan direktori sebagai berisi paket. Untuk informasi lebih lanjut, silakan lihat tautan dokumentasi Modul yang disediakan nanti.

Direktori kerja kami saat ini adalah satu tingkat di atas folder biasa yang disebut mypackage

$ ls
mypackage

Jika kita menjalankan interpreter python3 sekarang, kita dapat mengimpor dan menjalankan modul mymodule.py yang berisi fungsi myfunc yang diperlukan dengan cara yang berbeda berikut (Anda biasanya hanya memilih salah satu dari yang berikut):

>>> 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!

Dengan asumsi Python 3, ada dokumentasi yang sangat baik di: Modul

Dalam hal konvensi penamaan untuk paket dan modul, pedoman umum diberikan dalam PEP-0008 - silakan lihat Nama Paket dan Modul

Modul harus memiliki nama pendek, semua huruf kecil. Garis bawah dapat digunakan dalam nama modul jika itu meningkatkan keterbacaan. Paket-paket python juga harus memiliki nama-nama kecil, huruf kecil semua, meskipun penggunaan garis bawah tidak disarankan.

arcseldon
sumber
5
Penjelasan sederhana yang bagus. Bagaimana jika Anda ingin menyimpan folder lain di dalam mypackage?
Anuj Gupta
3
Termasuk benar-benar tergantung pada apa yang Anda tulis. Jika Anda meletakkan barang di luar fungsi pada modul Anda, Anda akan memecatnya saat memanggil seperti import mypackage. Jika Anda ingin mengimpor hanya fungsi dari modul (bahkan file) lebih baik digunakan from module import function. Dalam kasus subfolder from subfolder.module import functionsehingga Anda dapat memanggil function()tanpa memecat bagian kode lainnya. Juga, jangan gunakan from module import *jika Anda benar-benar tidak perlu.
m3nda
5
Satu-satunya pertanyaan yang tersisa adalah bagaimana saya bisa mendapatkan paket untuk mengimpor semuanya import mypackage? Menambahkan import mymoduleuntuk __init__.pytidak bekerja ..
576i
Penjelasan rapi! namun, saya punya pertanyaan apakah numpy adalah sebuah paket bagaimana saya bisa mengeksekusi numpy.cos (1) pada juru bahasa saya karena sepertinya itu adalah nama modul di antaranya hilang. Tidak?
user1935724
3
Bagaimana dengan pip?
whackamadoodle3000
199

Karena belum ada yang meliput pertanyaan OP ini:

Apa yang ingin saya lakukan:

Buat modul python dapat diinstal dengan "pip install ..."

Ini adalah contoh minimal absolut, menunjukkan langkah-langkah dasar mempersiapkan dan mengunggah paket Anda ke PyPI menggunakan setuptoolsdan twine.

Ini sama sekali bukan pengganti untuk membaca setidaknya tutorial , ada lebih dari itu tercakup dalam contoh yang sangat mendasar ini.

Membuat paket itu sendiri sudah tercakup oleh jawaban lain di sini, jadi mari kita asumsikan kita sudah membahas langkah itu dan struktur proyek kita seperti ini:

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

Agar dapat digunakan setuptoolsuntuk kemasan, kita perlu menambahkan file setup.py, ini masuk ke folder root dari proyek kami:

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

Minimal, kami menentukan metadata untuk paket kami, setup.pyakan terlihat seperti ini:

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='[email protected]',
    keywords=['example'],
    url='https://github.com/bgse/hellostackoverflow'
)

Karena kami telah menetapkan license='MIT', kami menyertakan salinan dalam proyek kami sebagai LICENCE.txt, di samping file readme di reStructuredText sebagai README.rst:

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

Pada titik ini, kami siap untuk mulai menggunakan kemasan setuptools, jika kami belum menginstalnya, kami dapat menginstalnya dengan pip:

pip install setuptools

Untuk melakukan itu dan membuat source distribution, di folder root proyek kami, kami memanggil kami setup.pydari baris perintah, menentukan kami ingin sdist:

python setup.py sdist

Ini akan membuat paket distribusi dan info telur kami, dan menghasilkan struktur folder seperti ini, dengan paket kami di dist:

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

Pada titik ini, kami memiliki paket yang dapat kami instal menggunakan pip, jadi dari root proyek kami (dengan asumsi Anda memiliki semua penamaan seperti dalam contoh ini):

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

Jika semuanya berjalan dengan baik, kita sekarang dapat membuka juru bahasa Python, saya akan mengatakan di suatu tempat di luar direktori proyek kami untuk menghindari kebingungan, dan mencoba menggunakan paket baru mengkilap kami:

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!'

Sekarang kami telah mengkonfirmasi paket menginstal dan berfungsi, kami dapat mengunggahnya ke PyPI.

Karena kami tidak ingin mencemari repositori langsung dengan eksperimen kami, kami membuat akun untuk repositori pengujian , dan menginstal twineuntuk proses unggah:

pip install twine

Sekarang kita hampir sampai, dengan akun kita dibuat, kita hanya mengatakan twineuntuk mengunggah paket kita, itu akan meminta kredensial kita dan mengunggah paket kita ke repositori yang ditentukan:

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

Kami sekarang dapat masuk ke akun kami di repositori tes PyPI dan mengagumi paket kami yang baru diunggah untuk sementara waktu, dan kemudian mengambilnya menggunakan pip:

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

Seperti yang bisa kita lihat, proses dasarnya tidak terlalu rumit. Seperti yang saya katakan sebelumnya, ada banyak lebih dari yang dibahas di sini, jadi silakan baca tutorial untuk penjelasan lebih mendalam.

bgse
sumber
Apakah paket saya akan diterbitkan setelahnya setuptools?
U10-Maju
@ U9-Maju Tidak, penerbitan selesai twine, tetapi Anda dapat menguji paket Anda secara lokal sebelum diterbitkan setelah Anda membuatnya setuptools.
bgse
9

Setelah Anda menentukan perintah yang Anda pilih, Anda dapat menarik dan melepas file yang disimpan ke folder Lib di file program python Anda.

>>> import mymodule 
>>> mymodule.myfunc()
Dreamatronix
sumber
2

Buat file dengan nama "hello.py"

Jika Anda menggunakan Python 2.x

def func():
    print "Hello"

Jika Anda menggunakan Python 3.x

def func():
    print("Hello")

Jalankan file. Kemudian, Anda dapat mencoba yang berikut ini:

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

Jika Anda ingin sedikit keras, Anda dapat menggunakan yang berikut:

Jika Anda menggunakan Python 2.x

def say(text):
    print text

Jika Anda menggunakan Python 3.x

def say(text):
    print(text)

Lihat yang ada di tanda kurung di samping define? Itu penting. Ini adalah salah satu yang dapat Anda gunakan di dalam define.

Teks - Anda dapat menggunakannya saat Anda ingin program mengatakan apa yang Anda inginkan. Menurut namanya, itu adalah teks. Saya harap Anda tahu apa artinya teks. Itu berarti "kata-kata" atau "kalimat".

Jalankan file. Kemudian, Anda bisa mencoba yang berikut jika Anda menggunakan Python 3.x:

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

Untuk Python 2.x - Saya kira hal yang sama dengan Python 3? Tidak ada ide. Perbaiki saya jika saya membuat kesalahan pada Python 2.x (Saya tahu Python 2 tetapi saya terbiasa dengan Python 3)

Kakkoiikun
sumber
2

Saya membuat proyek untuk dengan mudah memulai kerangka proyek dari awal . https://github.com/MacHu-GWU/pygitrepo-project .

Dan Anda dapat membuat proyek uji, katakanlah learn_creating_py_package,.

Anda dapat mempelajari komponen apa yang harus Anda miliki untuk tujuan yang berbeda seperti :

  • buat virtualenv
  • instal sendiri
  • jalankan unittest
  • jalankan cakupan kode
  • membuat dokumen
  • menyebarkan dokumen
  • jalankan unittest dalam versi python yang berbeda
  • gunakan untuk PYPI

Keuntungan menggunakan pygitrepoadalah bahwa mereka membosankan secara otomatis dibuat sendiri dan beradaptasi Anda package_name, project_name, github_account, document host service, windows or macos or linux.

Ini adalah tempat yang bagus untuk belajar mengembangkan proyek python seperti pro.

Semoga ini bisa membantu.

Terima kasih.

MacSanhe
sumber