Python Decoratorleri ve Observer Uygulaması

Share Button

Bugün bir python projesi için yazdığım kütüphanenin uzak sunucuyla yaptığı hareketleri loglaması için yeni bir geliştirme yapmam gerekti. Malum, henüz dilin acemisi olduğum için ilk olarak observer tasarım deseninin pythondaki uygulama şekillerini incelemeye koyuldum. Yapmak istediğim şey, tam olarak djangodaki signal modülünün benzeri küçük basit bir kütüphane bulup implemente etmek veya hızlıca yazmaktı.

Okuyup uyguladıkca python a hayranlığım bir kat daha artmaya başladı. Daha önce PHPİst etkinliğine gelen arkadaşlar hatırlayacaktır. Orada da observer tasarım desenini anlatırken loglama örneği üzeirnden gitmiştik. Observer tasarım deseninin PHP uyarlamasını kısaca hatırlayalım.

ObservableAbstract :

<?php
abstract class ObservableAbstract
{
    public function attach($eventName, ObserverInterface $observer)
    {
    	//...
    }

    protected function _triggerEvent($eventName, Event $event)
    {
    	/..
    }
}

ObserverInterface :

<?php
interface ObserverInterface
{
	public function invoke(Event $event);
}

LoggerObserver:

<?php
class LoggerObserver implements ObserverInterface
{
	public function invoke(Event $event)
	{
		// Loglama ile ilgili kodlar 
	}
}

…ve tabi ObserverInterface den türeyen yeni observer sınıfları, bu sınıfları ObservableAbstract ailesine bağlayan kodlar…

Peki pythonda ne yaptık ? Aynı işi yapmak için yine php tarafında olduğu gibi bir observable sınıfı ve gözlemcilerimizi atamak için kullanacğımız bir adet dekoratör yazdık.

eventmanager/__init__.py:

class ObservableAbstract(object):
	def __init__(self):
		self._observers = {}

	def attach(event_name, listener):
		self._observers.setdefault(event_name, []).append(listener)

	def _trigger_event(event_name, context):
		if event_name in self._observers:
			context.update({'event_name': event_name})
			for observer in self._observers.get(event_name):
				observer(context)

eventmanager/decorators.py:

from eventmanager import ObservableAbstract

def listener(instance, event_name):
	def wrap_func(func):
		if isinstance(isinstance, ObservableAbstract):
			instance.attach(event_name, func)

Observable ailesinden gelen olay tetiklemelerini dinlemek için, gözlemci olarak kullanacağınız fonksiyonların başına listener() dekoratörünü eklemeniz yeterli.

@listener(instance=MyApiInstance, event_name=AFTER_REQUEST)
def log_handler(context):
	with open('transaction.log', 'w+') as file:
		file.write(str(context))	
Share Button

About İbrahim Gündüz

1983 yılında İstanbul’da doğdu. İlkokul yıllarında cobol ve basic le olan tanışması, yazılıma olan ilgisini arttırdı 2005 yılında. Uludağ Üniversitesi Teknik Bilimler Meslek Yüksek Okulu Elektronik bölümünden mezun olan Gündüz, çeşitli alanlarda faaliyet gösteren kurumlarda yazılım geliştirici olarak görev almıştır. Mesleki ilgi alanları, ölçeklenebilir sistemler, uygulama entegrasyonları ve ödeme sistemleridir. Halen Markafoni back end geliştirici olarak çalışmaktadır.

Bir Cevap Yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir