Python OOP #2 – Sınıf Değişkenleri

apply_raise() adında yeni bir fonksiyon tanımlayalım. Bu fonksiyon işçilerin maaşlarını artıracak. Artırma miktarını raise_amount değişkeninde saklayacağım.

class Employee():

    number_of_emps = 0
    raise_amount = 1.04

    def __init__(self, fname, lname, pay):
        self.fname = fname
        self.lname = lname
        self.pay = pay
        self.mail = fname + "." + lname + "@company.com"

        Employee.number_of_emps += 1

    def fullname(self):
        return self.fname + " " + self.lname

    def apply_raise(self):
        self.pay = int(self.pay * self.raise_amount)

emp1 = Employee("Bob", "Hawkes", 5000)
emp2 = Employee("Alice", "Banas", 3500)

Eğer

print(emp1.pay)
emp1.apply_raise()
print(emp1.pay)

dersem çıktı 5000 ve 5200 şeklinde olacaktır. Burada tanımladığımız fonksiyon yardımıyla pay değişkenini değiştirdik. apply_raise() fonksiyonu tanımlamasını şu şekilde de yapabilirdik:

def apply_raise(self):
        self.pay = int(self.pay * Employee.raise_amount)

Burada raise_amount değişkenine erişmek için sınıf adını kullandık. Çünkü sınıf değişkenlerine sınıf veya nesne ile erişilebilir. Her iki kullanımda doğrudur.

Peki

Employee.raise_amount=1.05

print(emp1.raise_amount)
print(Employee.raise_amount)

yazdığımda çıktı ne olurdu? Burada açıkça görüldüğü gibi değişkeni sınıfla kullandığım zaman değişkenin yeni değeri o sınıftan türeyen tüm nesneleri etkileyecektir. Yani çıktı iki tane 1.05 olur. Ancak

emp1.raise_amount=1.05

print(emp1.raise_amount)
print(Employee.raise_amount)

yazdığımda bu çağırım sadece emp1 nesnesini etkileyecektir. Yani çıktı 1.05 ve 1.04 olur.

Sınıfımıza bir de number_of_emps değişkeni ekledim. Başlangıç fonksiyonunu her çağırdığımda bu değer bir artırılacak böylece toplam işçi sayısını saklamız olacağız. Bunu test etmek için şöyle bir kod parçacığı yazılabilir:

print(Employee.number_of_emps)

emp1 = Employee("Bob", "Hawkes", 5000)
emp2 = Employee("Alice", "Banas", 3500)

print(Employee.number_of_emps)

Çıktıda ne elde ettiniz?

Reklamlar

Python OOP #1 – Sınıflar ve Örnekleme

Bu seriyi hazırlarken Corey Schafer‘ın video derslerinden yararlandım.

Python’da nesne tabanlı programlama diğer diller ile neredeyse aynı. C++ bilen biri Python ile sınıf-nesne ilişkili kodlar yazmakta hiç zorlanmayacaktır. Tüm kavramlar burada da geçerli. Her zamanki gibi öncelikle sınıfla başlıyoruz. Sınıf, aynı temel özelliklere sahip nesneleri ifade eden bir kategori gibi düşünülebilir. Örneğin bu ve muhtemel bundan sonraki yazılarımda kullanacağım örnek kod üzerinden gidecek olursam, Employee() yani “İşçi” bir sınıftır. Ama bu çok genel bir tanımlama. Birçok kişi işçi sınıfına dahil olabilir. Bob ve Alice birer işçidir. Ancak cinsiyet, yaş, isim, boy gibi bir çok farklı özelliklere sahiptirler. Ama sonuçta ikisi de işçi sınıfına ait. Bu nedenle örneğimizde Bob ve Alice birer nesne oluyor.

class Employee():
    def __init__(self, fname, lname, pay):
        self.fname = fname
        self.lname = lname
        self.pay = pay
        self.mail = fname + "." + lname + "@company.com"

    def fullname(self):
        return self.fname + " " + self.lname

emp1 = Employee("Bob", "Hawkes", 5000)
emp2 = Employee("Alice", "Banas", 3500)

print(emp1.mail)
print(Employee.fullname(emp1))

Kod temelde iki bölümden oluşuyor. class Employee(): kısmında işçi sınıfını tanımlıyoruz. Ama bu sadece bir tanımlama. Yani henüz bu sınıfı kullanmış değiliz. Oluşturduğumuz sınıfı kullanmak için bu sınıfın özelliklerini taşıyan nesneler oluşturacağım ki buna da Pythonca’da “örnekleme” deniyor.
emp1 = Employee("Bob", "Hawkes", 5000) satırında emp1 adında ismi Bob Hawkes olan ve 5000 maaş alan bir işçi nesnesi üretiyoruz.

Görüldüğü üzere örnekleme işlemi fonksiyon kullanımına benziyor. Nesnenin özelliklerini sınıfa argüman olarak veriyoruz. Bu örnekleme işlemini daha zor yapabilirdim. Nasıl mı?

class Employee():
    pass

emp1 = Employee()

emp1.fname = "Bob"
emp1.lname = "Hawkes"
emp1.pay = 5000
emp1.mail = "Bob.Hawkes@company.com"

Diğerinden farklı olarak burada __init__() fonksiyonunu kullanmadım. Sonuçta nesnenin özelliklerini tek tek elimle girmek zorunda kaldım. Bu şekilde aynı sınıfa ait yüzlerce nesne olduğunu düşünün. Kod yazmak oldukça zor olurdu.

İlk örnekte kullandığım __init__ fonksiyonu bu işe yarıyor. Adını initialization yani “başlangıç” kelimesinden alan bu fonksiyon nesnelerin başlangıç değerleri almasını sağlıyor. C++ bilenler constructor dediğimde ne demek istediğimi anlayacaklardır.

Göze çarpan Self kelimesi başlangıç değeri ataması yaparken argüman olarak verdiğimiz nesneyi ifade ediyor. Eğer bunu kullanmazsam Python neye değer vereceğini bilemez.

Örnekte bir de fullname() fonksiyonu var ki bunu ben tanımladım. İşlevi nesnenin tam adını geri döndürüyor olması. Fonksiyonu kullanırken önce sınıfın adını sonra fonksiyon adını araya”.” koyarak kullandım. Bu Employee sınıfından fullname fonksiyonunu çağır anlamına geliyor.

Sınıfa ait fonksiyon kullanırken argüman olarak direk nesneyi verdim. Fonksiyon tanımlaması incelenirse nesnenin, Self yerine kullanıldığı görülebilir. Bu Self mantığını anlamak için güzel bir kullanım şekli ancak genelde sınıfa ait fonksiyonlar çağırılırken şu kullanım tercih edilir.

print(emp1.fullname())

Bu daha kısa bir kullanım ancak yeni başlayanlar için biraz kafa karıştırıcı olabilir. Burada değişkenlerde olduğu gibi nesneye ait bir fonksiyonu çağırıyoruz.Unutulmamalıdır ki bir sınıftan üretilen nesne, sınıfa ait her şeyi -değişkenler, fonksiyonlar vs.- alır.

Bir sonraki yazıda sınıf değişkenlerinden bahsedeceğim.