Merhaba arkadaşlar, bu kez açılan bir başlıkta belirlenen bir konuyu örneklerle anlatmaya çalışmak istiyorum. Evet böyle bir talep kimseden gelmedi ama forum kurallarına da aykırı değil herhalde. Belki, konuyu okuyan arkadaşlara faydası olur diye umuyorum.
Evet konuyu işlemeye geçelim:
# -*- coding: utf-8 -*-
# Fonksiyon ve Class Bezeyicileri
# -------------------------------
# 1. Fonksiyon Bezeyicileri
# -------------------------
# Örnek-1:
# --------
def f1(f):
def g1():
return "{}".format(f()).lower()
return g1 # <-- g1
# Fonksiyonumuzu test edelim:
@f1
def testf1():
return "TEST"
print(testf1())
# Aynı işlem, bezeyici olmadan aşağıdaki yöntemle de yapılabilir:
def f1_(f):
def g1():
return "{}".format(f()).lower()
return g1() # <-- g1()
def testf1_():
return "TEST"
print(f1_(testf1_))
# Örnek-2:
# --------
def f2(f):
def g2():
return {
i: i**2
for i in range(f())
}
return g2
@f2
def testf2():
return 10
print(testf2())
# Peki bir fonksiyon üzerinde birden fazla bezeyici
# kullanabilir miyiz?
# Aşağıdaki örneği inceleyelim:
# Örnek-3:
# --------
def f3(f):
def g3():
return [i for i in f()]
return g3
def f4(f):
def g4():
return f().lower().replace("e", ".")
return g4
@f3
@f4
def testf3f4():
return "MERHABA"
print(testf3f4())
# 2. Class Bezeyicileri
# classlarda kullanılan bezeyiciler fonksiyon bezeyicileriyle
# birbirlerine benzerler.
# Öncelikle aşağıdaki __init__() fonksiyonu içindeki
# '__x' değişkeninin sol tarafında iki tane alt çizgi
# olduğuna dikkatinizi çekmek isterim. Bu alt çizginin işlevi, x niteliğinin
# kullanımını kısıtlamaktır. x niteliğine erişmek
# istediğimizde daha farklı yollardan ona erişme imkanı
# sağlamak amacıyla bezeyiciler kullanacağız.
# Örnek-1:
# --------
class Sinif1:
def __init__(self):
self.__x = None
@property
def x(self):
return self.__x
@x.setter
def x(self, value):
"""x.setter bezeyicisi __x örnek niteliğini 'value'
isimli, kullanıcının gireceği bir değerle değiştiriyor"""
self.__x = value
@x.deleter
def x(self):
"""__x niteliğini silinebilir hale getiriyoruz."""
del self.__x
inst1 = Sinif1()
print(inst1.x)
inst1.x = 20
print(inst1.x)
del inst1.x
# Yukarıdaki sınıf içinde tanımlanan fonksiyonların yaptıkları
# işlemleri daha farklı yollardan da yapabilirdik tabiki.
# Aşağıdaki sinifin örnek fonksiyonlarının yaptığı iş
# yukarıdaki sinifin örnek fonksiyonlarının yaptığı işle
# aynıdır.
# Örnek-2:
# --------
class Sinif2:
def __init__(self):
self.__x = None
@property
def x(self):
return self.__x
def degistir(self, value):
self.__x = value
def sil(self):
del self.__x
inst2 = Sinif2()
print(inst2.x)
inst2.degistir(value=40)
print(inst2.x)
inst2.sil()
# Aşağıdaki sınıfın örnek fonksiyonları da
# diğer iki sınıfın örnek fonksiyonlarının
# yaptığı işlemin aynısını yapar.
# Örnek-3:
# --------
class Sinif3:
def __init__(self):
self.__x = None
def geri_donder(self):
return self.__x
def degistir(self, value):
self.__x = value
def sil(self):
del self.__x
# class içinde kullanılan bezeyicilerin
# birer fonksiyon olduğunu görüyorsunuz.
x = property(geri_donder)
x = x.setter(degistir)
x = x.deleter(sil)
inst3 = Sinif3()
print(inst3.x) # inst3.x = inst3.geri_donder()
inst3.degistir(value=60)
print(inst3.geri_donder())
inst3.sil()
# Yukarıdaki tüm classlar aşağıdaki class'ın
# benzeridir. Diğer sınıflarla birlikte aşağıdaki
# sınıf incelendiği taktirde, @property bezeyicisinin
# tam olarak ne işe yaradığının görülebileceğini düşünüyorum.
# Örnek-4:
# --------
class Sinif4:
def __init__(self):
self.__x = None
def geri_donder(self):
return self.__x
def degistir(self, value):
self.__x = value
def sil(self):
del self.__x
inst4 = Sinif4()
print(inst4.geri_donder())
inst4.degistir(value=10)
print(inst4.geri_donder())
inst4.sil()
print(inst4.geri_donder())
# Peki class'ımızda bir __init__ fonksiyonu
# tanımlamamış olsaydık, self.__x isimli örnek
# niteliği yerine __x isimli bir sınıf niteliği
# tanımlamış olsaydık?
# Örnek-5:
# --------
class Sinif5:
__x = None
def geri_donder(self):
return self.__x
def degistir(self, value):
self.__x = value
def sil(self):
del self.__x
# Sizce, bu durumda __x değişkenini tıpkı yukarıdaki
# sınıflarda olduğu gibi tamamen ortadan kaldırma gibi
# bir ihtimal olabilir mi?
# Hemen örnek üzerinde göstermeye çalışalım:
inst5 = Sinif5()
print(inst5.geri_donder()) # None değerini geri döndürdük.
inst5.degistir(value=10) # __x'in değerini değiştiriyoruz.
print(inst5.geri_donder()) # Bu kez değiştirdiğimiz değeri geri döndürdük.
inst5.sil() # _x'i silmeyi deneyelim.
print(inst5.geri_donder()) # __x silinmiş mi silinmemiş mi bir bakalım.
# Silme işlemi, __x niteliğinin değiştirdiğimiz özelliğini sildi,
# ancak __x'in kendisini silmedi.
# Halbuki yukarıdaki diğer sınıflarda __x niteliği siliniyordu.
# Bunun sebebi bu sınıfta silinenin __x'in örnek niteliği olmasıdır.
# İyi ama biz __init__ içinde bir örnek niteliği tanımlamadık.
# Biliyorsunuz sınıf niteliğine hem sınıf hem de örnek üzerinden erişilebilir.
# Yukarıdaki sınıfta da bu niteliğe örnek üzerinden erişiyoruz ve onu değiştirirken
# bir tane örnek oluşturuyoruz. Dolayısıyla silme işleminin örnek üzerinde geçerli
# olduğunu ancak sınıf üzerinde geçerli olmadığını söyleyebiliriz.
# Peki biz bir sınıf niteliğini nasıl silebiliriz?
# Hemen aşağıdaki örneğe bakalım.
# Örnek-6:
# --------
class Sinif6:
__x = None
@classmethod
def get(cls):
return cls.__x
@classmethod
def set(cls, value):
cls.__x = value
@classmethod
def sil(cls):
del cls.__x
cls1 = Sinif6
print(cls1.get())
cls1.set(value=10)
print(cls1.get())
cls1.sil()
print(cls1.get())