15. Property

Python, nesne yönelimli programlamayı çok daha kolay hale getiren property adında bir özelliğe sahiptir. Bu bölüm property konusuna ayrılmıştır.
Property konusuna başlamadan önce niye ihtiyaç olduğunu açıklayalım. Sıcaklığı  santigrat cinsinden alan ve Fahrenhayt fonksiyonuna sahip olan bir sınıf tasarlayalım.

Yukarıdaki örnekte sicaklik self.sicaklik olduğu için nesne üzerinden ulaşılabilir. Hatta değiştirilebilir. fahrenhayt fonksiyonu santigrat cinsinden alınan değeri fahrenhayt türüne çevirir.

Ulaşabileceğiniz değişkenleri görmek için “n01.__dict__” ifadesi kullanılabilir. Çıktı olarak bir dictionary döndürür, örneğin bu örnek için {‘sicaklik’: 80} değeri döndürülür.

Aslında sicaklik değerinin -273’ten küçük olmayacağına dair bir bilgi edindik. Yukarıdaki sınıfa göre sicaklik değişkeni kontrol edilmektedir. Aslında bir sorun ile karşılaştık, değişkeni kontrol edemiyoruz. Çözüm olarak fonksiyonlar üzerinden kontrol edebiliriz ve değişkeni private duruma getirebiliriz. Ancak property sayesinde fonksiyona gerek kalmadan bir çözüm oluşturmaya çalışacağız.

15.1. Get ve set ile çözüm

Öncelikle problemi get ve set fonksiyonları ile çözelim.

get fonksiyonu _sicaklik değerini döndürürken, set ile _sicaklik değeri ayarlanır. set bölümünde sıcaklık değerinin kontrolü de yapılıyor. Sıcaklık değeri -273’ten küçük girilirse raise ile bir exception üretilecektir. _sicaklik değişkeninin önündeki “_” bu değişkeni private yapar, bu sayede değiştirilmesi imkansız olur. Bu konu nesne yönelimli programlamada sarmallama (encapsulation) olarak adlandırılır. Ayrıca, yapıcı içinde set fonksiyonunu kullandık.

Evet, artık sicaklik değeri kontrol edilebilir duruma geldi. Şimdi get ve set fonksiyonları üzerinden sicaklik değerini değiştirelim.

Buraya kadar bir problem yok. Get ve set üzerinden çalıştığınız sürece değişken private olarak kalır. Ancak, Python değişkenleri dışarıdan tanımlamaya olanak tanır. Örneğin,

Program hata vermeden -400 değerini döndürür. Çünkü fonksiyon üzerinde veri alınmamıştır. Bu tanımlamadan sonra değişkenin private özelliği de bozulur. Şimdi benzer çözümü property ile yapalım.

15.2. Property çözümü

Property konusunu C# kullanmış geliştiriciler hatırlar. Bir fonksiyon yerine direkt bir değişken üzerinden get ve set işlemlerine olanak sağlayan bir yapı idi. Değişken olmasına rağmen bir kontrol işlemine tabii tutulabiliyordu. Property konusu Python’da çok benzer bir yapıya sahiptir. Basit bir örnekle açıklayalım:

sicaklik adında bir değişkenle get_sicaklik ve set_sicaklik fonksiyonları eşleştiriyor. Bundan sonra sicaklik üzerinden yapılan işlemler bu fonksiyonlar üzerinden geçer. Örneğin,

Her ne kadar property tanımlanmış olsa da fonksiyonlarda hala kullanılabilir. Ama örnekte olduğu gibi property kodu daha kısa ve kullanımı daha kolaydır. Peki property üzerinden -273’ten küçük bir değer alalım.

Fonksiyona girdiği görülüyor. Ancak, 15.1’de olduğu gibi _sicaklik değeri sınıf dışından, nesne üzerinden değiştirilebilir ve erişilebilir. Bu dudumda yine set bölümündeki kontrol aşılmış olur.

Kod hata vermeden çalıştı. Bu tür hatalar oluşmaması için fonksiyon veya property üzerinden değişkenlere ulaşmanızı öneririm. Her ne kadar Python “_” kullanımda private özelliği gibi görse de bir kez aşıldığında kullanılabiliyor.

15.3. Property fonksiyonu

Python’da property() bir property nesnesi oluşturmak ve döndürmek için var olan yerleşik bir fonksiyondur. Aldığı parametreler:

property(fget=None, fset=None, fdel=None, doc=None)

fget get fonksiyonu işaret etmek, fset set fonksiyonunu işaret etmek, fdel silme fonksiyonunu işaret etmek ve doc ise yorum/açıklama için kullanılır. Tüm parametreler seçimliktir.

15.4. Property ve decorators

Python’da geliştiriciler decorator kullanarak property tanımlama şansına sahiptir. Örneğimizi decorator kullanarak tekrar düzenleyelim.

Bir önceki sınıfa göre get bölümü direkt property ismini aldı. @property decorator’ı eklendi. Ardından @sicaklik.setter ile set fonksiyonuna bağlandı. Seçim sizin, hepsi birbirinden güzel çözümler…