BAB 11: Cetakan dan Pembungkus: Objek, Kelas, dan Dekorator
Studi kasus: "Kok perintah QGIS ditulis dengan titik di tengah?" #
Analis Muda membaca skrip PyQGIS dan melihat baris seperti petak.featureCount() dan layer.fields(). Titik di tengah dan kurung di ujung itu apa artinya? Di sebagian skrip, ada pula kata class dan tanda @ di atas fungsi. Semua itu membuka satu gagasan yang membuat PyQGIS dan ArcPy terasa masuk akal: objek.
Konsep: kelas dan objek dalam tiga kalimat #
Sebuah kelas adalah cetakan, dan sebuah objek adalah barang yang dicetak darinya. Bayangkan cetakan kue: satu cetakan, banyak kue, dan tiap kue punya isinya sendiri. Objek membawa isi (disebut atribut) dan kemampuan (disebut metode), dan keduanya diakses dengan titik: objek.isi dan objek.kemampuan().

Istilah baru di bagian ini:
- Kelas (class): cetakan yang dibuat dengan kata
class. - Objek: hasil cetakan. Bisa banyak, dan masing-masing punya isi sendiri.
- Atribut: isi yang menempel pada objek, misalnya
p1.luas_ha. - Metode: fungsi yang menempel pada objek, misalnya
p1.kategori().
Membuat kelas sendiri #
class Petak:
def __init__(self, kode, luas_ha):
self.kode = kode
self.luas_ha = luas_ha
def luas_m2(self):
return self.luas_ha * 10000
def kategori(self):
if self.luas_ha > 5:
return "besar"
return "kecil"
p1 = Petak("P-01", 4.0)
p2 = Petak("P-02", 8.0)
print(p1.kode, p1.luas_m2(), p1.kategori())
print(p2.kode, p2.luas_m2(), p2.kategori())Penjelasannya:
class Petak:membuat cetakan bernamaPetak.def __init__(self, kode, luas_ha):adalah pembuat objek. Python memanggilnya otomatis saat Anda menulisPetak(...). Dua garis bawah di kiri dan kanan namanya itu wajib.selfberarti "objek yang sedang dibuat atau dipakai". Ia selalu menjadi parameter pertama sebuah metode. Anda tidak mengisinya sendiri saat memanggil.self.kode = kodemenyimpan bahan ke dalam objek sebagai atribut.luas_m2dankategoriadalah metode: fungsi biasa yang dipasang di dalam kelas.p1 = Petak("P-01", 4.0)mencetak satu objek.p2mencetak yang lain. Isi mereka terpisah.
P-01 40000.0 kecil
P-02 80000.0 besarPewarisan: kelas turunan #
Sebuah kelas boleh mewarisi kelas lain: ia mengambil semua isi dan kemampuannya, lalu mengganti sebagian. Tulis nama kelas induk di dalam kurung.
class Petak:
def __init__(self, kode, luas_ha):
self.kode = kode
self.luas_ha = luas_ha
def luas_m2(self):
return self.luas_ha * 10000
def kategori(self):
return "biasa"
class PetakLindung(Petak):
def kategori(self):
return "lindung"
p3 = PetakLindung("P-03", 2.0)
print(p3.kode, p3.kategori(), p3.luas_m2())PetakLindung tidak menulis ulang __init__ dan luas_m2: ia mengambilnya dari Petak. Ia hanya mengganti kategori.
P-03 lindung 20000.0Pewarisan inilah yang dipakai QGIS. Skrip algoritma Processing di Buku M4 diawali class KerapatanHotspot(QgsProcessingAlgorithm):. Artinya: kelas baru Anda mewarisi seluruh kemampuan dasar algoritma QGIS, lalu Anda mengisi bagian yang khas, seperti nama dan parameternya.
Dekorator: pembungkus fungsi #
Sebuah dekorator adalah pembungkus yang dipasang di atas fungsi dengan tanda @. Bayangkan kotak kado: fungsi di dalamnya sama, tetapi ada tambahan pada pembungkusnya.
def catat(fungsi):
def bungkus(*args, **kwargs):
print("memanggil", fungsi.__name__)
return fungsi(*args, **kwargs)
return bungkus
@catat
def ke_hektar(m2):
return m2 / 10000
print(ke_hektar(40000))Penjelasannya:
catatmenerima sebuah fungsi, lalu mengembalikan fungsi pembungkus yang mencetak catatan sebelum menjalankan yang asli.@catatdi atasdef ke_hektarsama dengan menuliske_hektar = catat(ke_hektar).*argsdan**kwargsmenampung semua argumen apa pun, lalu meneruskannya.
memanggil ke_hektar
4.0Anda hampir tidak perlu menulis dekorator sendiri. Yang penting, Anda bisa mengenalinya di skrip orang lain: tanda @ di atas def berarti "fungsi ini dibungkus dengan fasilitas tertentu".
Skrip yang dibedah: dua gaya algoritma Processing #
Di Buku M4 ada dua skrip yang membuat alat baru untuk QGIS. Skrip pertama bergaya kelas, skrip kedua bergaya dekorator. Di Bagian B (Bab 27) keduanya dibahas lengkap dan dijalankan. Di sini kita hanya mengenali bentuknya.
Tujuan. Mengenali kelas dan dekorator di skrip nyata.
Bahan. Tidak ada. Potongan ini tidak dijalankan, karena butuh Processing QGIS.
Potongan 1: gaya kelas (kerapatan_hotspot.py).
class KerapatanHotspot(QgsProcessingAlgorithm):
PETAK = "PETAK"
TITIK = "TITIK"
BATAS = "BATAS"
HASIL = "HASIL"
def createInstance(self):
return KerapatanHotspot()
def name(self):
return "kerapatan_hotspot"Penjelasan baris demi baris. Nomor baris dihitung dari potongan di atas.
| Baris | Tulisan | Artinya |
|---|---|---|
| 1 | class KerapatanHotspot(QgsProcessingAlgorithm): | Buat kelas baru yang mewarisi QgsProcessingAlgorithm, cetakan algoritma milik QGIS. |
| 2-5 | PETAK = "PETAK" dan tiga baris lain | Empat atribut tetap berupa teks. Nama berhuruf besar menandakan nilainya tidak berubah. Dipakai sebagai nama parameter. |
| 7-8 | def createInstance(self): return KerapatanHotspot() | Metode yang wajib ada. Ia mencetak satu salinan baru kelas ini bila QGIS memintanya. |
| 10-11 | def name(self): return "kerapatan_hotspot" | Metode yang memberi nama alat. QGIS memanggilnya sendiri. |
Potongan 2: gaya dekorator (tambah_luas_ha.py).
@alg(name="tambah_luas_ha", label="Tambah kolom luas (hektare)", group="kehutanan", group_label="Kehutanan")
@alg.input(type=alg.SOURCE, name="INPUT", label="Layer poligon", types=[2])
@alg.input(type=alg.SINK, name="OUTPUT", label="Hasil")
def tambah_luas_ha(instance, parameters, context, feedback, inputs):| Baris | Tulisan | Artinya |
|---|---|---|
| 1 | @alg(name=..., label=..., group=...) | Dekorator yang menjadikan fungsi di bawahnya sebuah alat QGIS, lengkap dengan nama, label, dan kelompoknya. |
| 2 | @alg.input(type=alg.SOURCE, ...) | Dekorator tambahan: menyatakan satu masukan berupa layer poligon. |
| 3 | @alg.input(type=alg.SINK, ...) | Dekorator tambahan: menyatakan satu keluaran berupa layer hasil. |
| 4 | def tambah_luas_ha(...) | Fungsi yang dibungkus. Isinya menghitung luas dan menulis hasilnya. |
Hasil. Potongan ini tidak mencetak apa-apa. Di Bab 27 Anda akan melihat alat-alat ini muncul di kotak peralatan Processing QGIS.
Bagian yang boleh diubah. Nama, label, dan grup alat boleh Anda ganti dengan tulisan sendiri. Nama parameter (misalnya "INPUT") harus sama di semua tempat yang memakainya.
Jebakan.
- Lupa
self. Metode yang tidak menyebutselfsebagai parameter pertama menghasilkanTypeErrorsaat dipanggil, karena Python tetap menyodorkan objeknya. - Lupa mengisi atribut lewat
self. Menuliskode = kodedi__init__hanya membuat kotak sementara. Isinya hilang. Tulisself.kode = kode. - Salah mewarisi. Kelas turunan harus menyebut induknya di dalam kurung. Tanpa itu, ia tidak mendapat kemampuan induk.
Latihan variasi. Tambahkan metode kerapatan(self, jumlah_titik) ke kelas Petak pada contoh di atas. Metode itu mengembalikan jumlah titik dibagi luas hektare. Uji dengan petak 8 hektare dan 4 titik.
Contoh jawaban:
class Petak:
def __init__(self, kode, luas_ha):
self.kode = kode
self.luas_ha = luas_ha
def kerapatan(self, jumlah_titik):
return jumlah_titik / self.luas_ha
p = Petak("P-02", 8.0)
print(p.kerapatan(4))0.5Cek paham #
- Apa beda kelas dan objek?
- Apa arti
selfdi dalam sebuah metode? - Apa yang dilakukan tanda
@di atas sebuah fungsi?
Jawaban.
- Kelas adalah cetakan. Objek adalah barang yang dicetak dari cetakan itu, dan tiap objek punya isi sendiri.
selfberarti objek yang sedang dipakai. Lewatself, metode membaca dan mengubah isi objek itu.- Menandai bahwa fungsi di bawahnya dibungkus oleh dekorator, yaitu fungsi lain yang menambahkan fasilitas.
Kesalahan umum #
- Memanggil metode tanpa kurung.
p1.kategorihanya menunjuk fungsinya. Perbaikan: tulisp1.kategori(). - Mengira dua objek berbagi isi. Tiap objek membawa isinya sendiri. Perbaikan: ubah isi lewat objek yang dimaksud.
- Takut pada
classdan@. Perbaikan: pada tahap ini cukup kenali bentuknya. Menulisnya sendiri baru dibutuhkan di Bab 27.
Ringkasan dan latihan #
- Kelas adalah cetakan, objek adalah barang cetakan. Objek punya atribut (isi) dan metode (kemampuan).
__init__membuat objek,selfmenunjuk objek itu.- Pewarisan mengambil isi kelas induk, dekorator membungkus fungsi.
Latihan. Buat kelas Layer dengan atribut nama dan jumlah_fitur, serta metode ringkas() yang mengembalikan kalimat "<nama> memuat <jumlah> fitur". Buat dua objek, lalu cetak ringkasan keduanya.
Tabel perbandingan: tiga hal yang mirip tetapi berbeda #
| Hal | Fungsi | Metode |
|---|---|---|
| Letak | Berdiri sendiri | Di dalam kelas |
| Cara memanggil | ke_hektar(40000) | p1.luas_m2() |
| Bahan khusus | Hanya parameter | Selalu ada self |