Ternyata metaclass di Python itu sangat menarik karena kita bisa melakukan ilmu hitam :D Salah satu ilmu hitam yang sedang/akan saya pakai adalah membuat deklarasi kelas yang baru saja dibuat menjadi lenyap secara tiba2 dan alih-alih kita mendapatkan sebuah objek/instance dari kelas tersebut.
Mengapa saya memerlukan sesuatu yang "aneh" seperti ini? Singkatnya saya sedang membuat semacam domain specific language yang berbasiskan Python. Dengan menggunakan trik sulap di atas, saya bisa membuat bahasa yang saya buat tadi menjadi lebih mudah dipakai. Maaf kalo saya blom bisa menjelaskan dg lebih detail.
Di Python, metaclass bisa digambarkan sebagai sebuah kode yang dijalankan saat sebuah kelas dideklarasikan. Dengan demikian kita bisa mengutak atik wujud sebuah kelas sebelum kelas teresebut siap dipakai. Contoh penggunaan dasarnya adalah sebagai berikut.
class MetaProvinsi(type):
def __new__(cls, name, bases, attrs):
return type.__new__(cls, name, bases, attrs)
class Provinsi(object):
__metaclass__ = MetaProvinsi
Pada contoh di atas, ada sebuah kelas bernama Provinsi yang memiliki metaclass MetaProvinsi. Kode pada fungsi __new__ di atas adalah bagian kode yang dapat diisi untuk mengubah wujud kelas Provinsi. Fungsi ini menerima 4 buah parameter yaitu:
clsyang menunjuk ke diri sendiri (yaituMetaProvinsi),nameyang berisi nama kelas yang dibuat (dalam contoh di atas,nameberisi Provinsi),basesyang berisi daftar kelas yang diturunkan oleh siProvinsi(yaituobject), danattrsyang berupa sebuah dictionary berisi daftar atribut (instance variables dan/atau methods) dariProvinsi.
Metaclass pada contoh di atas masih tidak melakukan hal apa-apa sehingga kelas Provinsi tsb sebenarnya tidak mengalami perubahan apa-apa. Sekarang mari kita ubah sedikit contoh di atas.
class MetaKabupaten(type):
def __new__(cls, name, bases, attrs):
attrs['nama_kelas'] = name
return type.__new__(cls, name, bases, attrs)
class Kabupaten(object):
__metaclass__ = MetaKabupaten
Kali ini kita mengubah dict attrs dengan menambahkan sebuah isian dengan kunci nama_kelas yang berisi nilai dari variabel name, yaitu nama kelas yang baru saja dibuat yaitu Kabupaten.
Apa bedanya contoh pertama dengan kedua? mari kita buat objek dari kelas Provinsi dan Kabupaten yang sudah dideklarasikan di atas.
p = Provinsi()
print p.nama_kelas
Andai kode di atas dijalankan, maka Python akan mengatakan bahwa atribut nama_kelas tidak ditemukan pada objek dari kelas Provinsi
AttributeError: 'Provinsi' object has no attribute 'nama_kelas'
Alasannya sudah jelas karena pada saat mendeklarasikan kelas Provinsi (maupun saat menginisialisasi kelas tersebut), kita tidak pernah membuat sebuah instance variable bernama nama_kelas. Sekarang kita coba dengan kelas Kabupaten
k = Kabupaten()
print k.nama_kelas
Bukan sulap bukan sihir, Python dapat dijalankan sampai selesai dan kita mendapat sebuah keluaran di layar seperti berikut.
Kabupaten
Keluaran tersebut dihasilkan dari k.nama_kelas yaitu nilai sebuah instance variable bernama nama_kelas dari objek k yang dibangun dari kelas Kabupaten. Kapan instance variable nama_kelas tersebut hadir? Jawabannya adalah pada saat kelas Kabupaten tersebut dibuat, lebih tepatnya dilakukan oleh metaclass MetaKabupaten.
Sekian dulu pengantar penggunaan Metaclass dari saya. Lain kali saya contohkan ilmu hitam yg sedang saya pakai maupun contoh pe(nyalah)gunaan lainnya. Contoh kode bisa dilihat di https://gist.github.com/814525
2 komentar:
propinsi!
biar kate aye orang sunda, ve mah tetep ve bukan pe :P http://id.wikipedia.org/wiki/Provinsi
Poskan Komentar