2.19. Menulis modul

Setiap file .py adalah sebuah modul. Memecah skrip yang berkembang ke beberapa file membuat setiap file tetap singkat dan memungkinkan helper umum dibagikan antar skrip.

2.19.1. Memecah skrip

Pindahkan sekelompok fungsi terkait ke dalam file mereka sendiri:

camera_utils.py

def banner():
    print("OpenMV")

def label(text):
    return "[" + text + "]"

main.py

import camera_utils

camera_utils.banner()
print(camera_utils.label("ready"))

Output:

OpenMV
[ready]

Kedua file berada berdampingan di direktori yang sama. Ketika main.py berjalan, import camera_utils membaca camera_utils.py sekali, mengeksekusi pernyataan tingkat atasnya, dan mengikat objek modul yang dihasilkan ke nama camera_utils di main. Sebuah import camera_utils kedua dari mana saja mengembalikan objek yang sama -- modul di-cache setelah pemuatan pertama mereka.

Nama modul berasal dari nama filenya, sehingga camera_utils.py diimpor sebagai import camera_utils.

2.19.2. Modul multi-file (paket)

Sebuah modul juga bisa berupa direktori file daripada sebuah .py tunggal. Nama direktori menjadi nama modul, dan file-file di dalamnya adalah submodul-nya:

camera_utils/
    __init__.py
    text.py
    timing.py

__init__.py adalah file yang berjalan ketika paket itu sendiri diimpor; bisa kosong, atau bisa mengekspor ulang nama-nama yang dipilih dari submodul. Submodul diakses dengan nama bertitik:

import camera_utils.text
from camera_utils.timing import elapsed

camera_utils.text.label("ready")

Di dalam paket, submodul dapat mencapai satu sama lain baik dengan nama bertitik lengkap atau dengan impor relatif yang menggunakan titik terdepan untuk berarti "paket ini":

camera_utils/timing.py

from . import text             # the sibling submodule

def stamp(value):
    return text.label(str(value))

Untuk mengambil nama tertentu sebagai gantinya, beri nama setelah sibling bertitik:

from .text import label

def stamp(value):
    return label(str(value))

Impor relatif membuat paket mandiri: mengganti nama direktori paket tidak memerlukan pengeditan setiap submodul.

Gunakan paket ketika sebuah file tunggal tumbuh melampaui ukuran yang nyaman, atau ketika sekumpulan modul terkait cocok bersama di bawah satu namespace. Untuk skrip sehari-hari, sebuah file .py tunggal sudah cukup.

2.19.3. Guard __name__

Setiap modul memiliki nama bawaan __name__. Nilainya bergantung pada cara file digunakan:

  • Ketika file dijalankan langsung, __name__ diatur ke string "__main__".

  • Ketika file diimpor oleh skrip lain, __name__ diatur ke nama modul -- nama file tanpa .py.

Idiom yang menggunakan ini adalah:

label_util.py

def label(text):
    return "[" + text + "]"

if __name__ == "__main__":
    print(label("self-test"))

Output (ketika dijalankan langsung):

[self-test]

Ketika file yang sama diimpor sebagai gantinya, __name__ diatur ke nama modul, sehingga blok if dilewati dan tidak ada yang dijalankan tambahan:

>>> import label_util
>>> label_util.__name__
'label_util'

Gunakan pola ini untuk melampirkan uji asap cepat atau demo ke file perpustakaan tanpa mengganggu skrip yang mengimpornya.