Modul (dan paket) adalah cara Pythonic yang bagus untuk membagi program Anda menjadi ruang nama terpisah, yang tampaknya menjadi tujuan implisit dari pertanyaan ini. Memang, saat saya mempelajari dasar-dasar Python, saya merasa frustrasi dengan kurangnya fitur cakupan blok. Namun begitu saya memahami modul Python, saya dapat dengan lebih elegan mewujudkan tujuan saya sebelumnya tanpa perlu cakupan blok.
Sebagai motivasi, dan untuk mengarahkan orang ke arah yang benar, menurut saya akan berguna untuk memberikan contoh eksplisit dari beberapa konstruksi pelingkupan Python. Pertama saya menjelaskan upaya saya yang gagal dalam menggunakan kelas Python untuk mengimplementasikan lingkup blok. Selanjutnya saya menjelaskan bagaimana saya mencapai sesuatu yang lebih berguna menggunakan modul Python. Di akhir saya menguraikan aplikasi praktis dari paket untuk memuat dan memfilter data.
Mencoba lingkup blok dengan kelas
Untuk beberapa saat saya berpikir bahwa saya telah mencapai lingkup blok dengan menempelkan kode di dalam deklarasi kelas:
x = 5
class BlockScopeAttempt:
x = 10
print(x)
print(x)
Sayangnya ini rusak ketika suatu fungsi didefinisikan:
x = 5
class BlockScopeAttempt:
x = 10
print(x)
def printx2():
print(x)
printx2()
Itu karena fungsi yang didefinisikan dalam kelas menggunakan cakupan global. Cara termudah (meskipun bukan satu-satunya) untuk memperbaikinya adalah dengan menentukan kelas secara eksplisit:
x = 5
class BlockScopeAttempt:
x = 10
print(x)
def printx2():
print(BlockScopeAttempt.x)
printx2()
Ini tidak begitu elegan karena seseorang harus menulis fungsi secara berbeda tergantung pada apakah mereka dimuat dalam sebuah kelas atau tidak.
Hasil yang lebih baik dengan modul Python
Modul sangat mirip dengan kelas statis, tetapi modul jauh lebih bersih menurut pengalaman saya. Untuk melakukan hal yang sama dengan modul, saya membuat file yang dipanggil my_module.py
di direktori kerja saat ini dengan konten berikut:
x = 10
print(x)
def printx():
global x
print(x)
Kemudian di file utama saya atau sesi interaktif (misalnya Jupyter), saya lakukan
x = 5
import my_module
my_module.printx()
print(x)
Sebagai penjelasan, setiap file Python mendefinisikan modul yang memiliki namespace global sendiri. Mengimpor modul memungkinkan Anda mengakses variabel di namespace ini dengan .
sintaks.
Jika Anda bekerja dengan modul dalam sesi interaktif, Anda dapat mengeksekusi dua baris ini di awal
%load_ext autoreload
%autoreload 2
dan modul akan dimuat ulang secara otomatis saat file terkait diubah.
Paket untuk memuat dan memfilter data
Ide paket adalah sedikit perluasan dari konsep modul. Paket adalah direktori yang berisi file (mungkin kosong) __init__.py
, yang dijalankan saat diimpor. Modul / paket dalam direktori ini dapat diakses dengan .
sintaks.
Untuk analisis data, saya sering kali perlu membaca file data besar dan kemudian secara interaktif menerapkan berbagai filter. Membaca file membutuhkan waktu beberapa menit, jadi saya hanya ingin melakukannya sekali. Berdasarkan apa yang saya pelajari di sekolah tentang pemrograman berorientasi objek, saya dulu percaya bahwa seseorang harus menulis kode untuk memfilter dan memuat sebagai metode di kelas. Kerugian utama dari pendekatan ini adalah jika saya kemudian mendefinisikan ulang filter saya, definisi kelas saya berubah, jadi saya harus memuat ulang seluruh kelas, termasuk datanya.
Saat ini dengan Python, saya mendefinisikan sebuah paket bernama my_data
yang berisi submodul bernama load
dan filter
. Di dalam filter.py
I dapat melakukan impor relatif:
from .load import raw_data
Jika saya memodifikasi filter.py
, maka autoreload
akan mendeteksi perubahan. Itu tidak memuat ulangload.py
, jadi saya tidak perlu memuat ulang data saya. Dengan cara ini saya dapat membuat prototipe kode pemfilteran saya di notebook Jupyter, membungkusnya sebagai fungsi, dan kemudian memotong-tempel dari notebook saya langsung ke filter.py
. Mengetahui hal ini merevolusi alur kerja saya, dan mengubah saya dari seorang yang skeptis menjadi penganut “Zen of Python”.
One purpose (of many) is to improve code readability
- Kode Python, ditulis dengan benar (yaitu, mengikuti zen python ) tidak perlu hiasan seperti itu agar dapat dibaca. Faktanya, ini adalah salah satu dari (banyak) hal yang saya suka tentang Python.