blog posts

Python’da sınıf yöntemini basit bir dille öğretmek

Python, temiz ve verimli kod yazmak için çeşitli araçlar ve teknikler sağlayan güçlü bir nesne yönelimli programlama (OOP) dilidir. Bu araçlardan biri de sınıf düzeyinden örnek düzeyine kadar erişilebilen yöntemleri tanımlamamızı sağlayan Classmethod dekoratörüdür. Maktab Khuneh dergisinden çıkan bu yazımızda Python’da Classmethod’u inceleyip kullanımlarını, avantajlarını ve pratik örneklerini inceleyeceğiz.

Python’da Classmethod nedir?

Python’daki Classmethod, bir sınıfın örneğiyle değil, bir sınıfla sınırlı olan özel bir yöntem türüdür. Bu yöntem @classmethod dekoratörü kullanılarak tanımlanır ve genellikle yöntem tanımının üstüne yerleştirilir. Python’da Classmethod’un sözdizimi aşağıdaki gibidir:

class MyClass:
@classmethod
def my_classmethod(cls, arg1, arg2, ...):
    # method implementation

@classmethod dekoratörü, yöntemin sınıfın bir alt yöntemi olduğunu ve sınıfın bir örneğine değil, sınıfın kendisine eklenmesi gerektiğini belirtmek için kullanılır. Sınıf yönteminin ilk parametresine genellikle sınıfın kendisini ifade eden cls adı verilir. Bu, sınıf yönteminin sınıf düzeyindeki özelliklere ve yöntemlere erişmesine ve bunları değiştirmesine olanak tanır. Bir sınıf yönteminde, sınıfa ve onun özelliklerine veya yöntemlerine atıfta bulunmak için cls’yi kullanabiliriz. Gerektiğinde herhangi bir ek parametreyi sınıf yöntemine de aktarabiliriz.

Bir sınıf yöntemini çağırmak için, sınıfın bir örneğini oluşturmadan, sınıf adını ve ardından yöntem adını kullanabiliriz. Aşağıdaki örnek bunu göstermektedir:

MyClass.my_classmethod(arg1, arg2, ...)

Python’da sınıf yönteminin uygulanması

Python’daki Classmethod, kodlamada birçok kullanım ve avantaj sunar; bunlardan en önemlileri aşağıda belirtilmiştir.

Sınıf düzeyindeki özelliklere erişim

Sınıf yöntemi kullanmanın temel avantajlarından biri, sınıf düzeyindeki özelliklere erişmemize ve bunları değiştirmemize olanak sağlamasıdır. Sınıf düzeyindeki özellikler bir sınıfın tüm örnekleri tarafından paylaşılır ve bunların bir sınıf yöntemi kullanılarak değiştirilmesi o sınıfın tüm örneklerini etkiler. Bu, sınıfın tamamıyla ilgili bilgileri güncellemek veya almak istediğimiz senaryolarda yararlı olabilir.

Alternatif üreticiler sağlamak

Python’da Classmethod’un bir diğer yaygın kullanımı, bir sınıf için alternatif kurucular sağlamaktır. Örneğin, farklı giriş formatlarını kullanarak veya harici veri kaynaklarından bir sınıfın örneklerini oluşturmak isteyebiliriz. Bir sınıf yöntemi kullanarak, farklı girdi parametrelerini alabilen ve sınıfın örneklerini döndürebilen alternatif kurucular tanımlayabiliriz. Bu, kodumuzun esnekliğini ve kullanılabilirliğini artırmaya yardımcı olabilir.

Sınıf düzeyinde işlemlerin uygulanması

sınıf yöntemi aynı zamanda sınıf düzeyinde ilgili işlemleri gerçekleştirmek için de kullanılabilir. Örneğin, sınıfın örneklerini sıralamak veya tüm örnekler üzerinde toplu güncelleme gerçekleştirmek gibi sınıf düzeyindeki işlemleri gerçekleştirmek için bir sınıf yöntemi tanımlayabiliriz. Bu, kodumuzu basitleştirebilir ve düzenleyebilir.

Python’da sınıf yöntemi örnekleri

Yazının bu bölümünde kullanıcıların Python’da bu konuyu daha iyi anlayabilmeleri için Python’daki bazı pratik sınıf yöntemleri örnekleri sunulacaktır.

Örnek 1: Sınıf düzeyinde bir sayacın uygulanması

class MyClass:
    counter = 0

    def __init__(self):
        MyClass.counter += 1

    @classmethod
    def get_instance_count(cls):
        return cls.counter

# Usage
obj1 = MyClass()
obj2 = MyClass()
print(MyClass.get_instance_count())  # Output: 2

Yukarıdaki Classmethod örneğinin Python’daki çıktısı aşağıdaki gibidir:

Yukarıdaki örnekte, sınıf düzeyinde bir counter özelliği tanımlıyoruz ve sayaç değerine erişip onu döndürmek için get_instance_count() sınıf yöntemini kullanıyoruz. MyClass’ın bir örneği her oluşturulduğunda sayaç artırılır. Class yöntemini kullanarak counter özelliğine sınıf düzeyinde erişebilir ve bunları değiştirebiliriz.

Örnek 2: Alternatif kurucuların uygulanması

import json

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def __repr__(self):
        return f"Person(name={self.name}, age={self.age})"

    @classmethod
    def from_json(cls, json_str):
        data = json.loads(json_str)
        return cls(data['name'], data['age'])

# Usage
json_str = '{"name": "kami", "age": 28}'
person = Person.from_json(json_str)
print(person)  

Yukarıdaki örneğin çıktısı aşağıdaki gibidir:

Yukarıdaki örnekte parametre olarak name ve age alan __init__ metodu ile Person sınıfını tanımladık. Ayrıca Person nesnelerinin dize gösterimini döndürmek için bir __repr__ yöntemi de tanımlarız. Ek olarak, bir JSON dizesini girdi olarak alan, onu ayrıştıran ve çıkarılan verilerden bir Person nesnesi oluşturan from_json sınıfının bir yöntemini tanımlayacağız. Bu, from_json sınıf yöntemini kullanarak JSON verilerinden Person örnekleri oluşturmamıza olanak tanır ve nesneler oluşturmak için alternatif bir kurucu sağlar.

Örnek 3: İşlemlerin sınıf düzeyinde uygulanması

class Circle:
    pi = 3.14159

    def __init__(self, radius):
        self.radius = radius

    def area(self):
        return Circle.pi * self.radius ** 2

    @classmethod
    def change_pi(cls, new_pi):
        cls.pi = new_pi

# Usage
circle1 = Circle(5)
print(circle1.area())  # Output: 78.53975

Circle.change_pi(3.14)  # Changing the value of pi at the class level

circle2 = Circle(3)
print(circle2.area())  # Output: 28.26

Bu Classmethod örneğinin Python’daki çıktısı aşağıdaki gibidir:

Yukarıdaki örnekte pi özelliğine sahip bir Circle sınıfı ve yarıçapına göre dairenin alanını hesaplayan bir alan yöntemi tanımladık. Ayrıca pi’nin değerini sınıf düzeyinde güncellememizi sağlayan change_pi sınıf yöntemini de tanımlıyoruz. Sınıfın tüm örneklerini etkileyen sınıf düzeyindeki işlemleri uygulamak için Python’da Classmethod’u nasıl kullanabileceğimizi gösterir.

Python’da Classmethod’un pratik bir örneği

Bu bölümde gerçek bir Python örneği incelenecektir. Banka hesaplarını temsil eden BankAccount sınıfının bir örneğini ele alalım. Oluşturulan toplam banka hesabı sayısını takip etmek ve her hesap için benzersiz bir hesap numarası sağlamak için Python’daki Classmethod’u kullanıyoruz.

class BankAccount:
    total_accounts = 0

    def __init__(self, owner, balance):
        self.owner = owner
        self.balance = balance
        BankAccount.total_accounts += 1

    def deposit(self, amount):
        self.balance += amount

    def withdraw(self, amount):
        if self.balance >= amount:
            self.balance -= amount
        else:
            print("Insufficient balance")

    def get_balance(self):
        return self.balance

    @classmethod
    def get_total_accounts(cls):
        return cls.total_accounts

    @classmethod
    def create_account(cls, owner, balance):
        return cls(owner, balance)

# Usage
account1 = BankAccount("John", 1000)
account2 = BankAccount("Jane", 5000)

print(BankAccount.get_total_accounts())  # Output: 2

account3 = BankAccount.create_account("Alice", 2000)
print(BankAccount.get_total_accounts())  # Output: 3

Çıktı aşağıdaki gibidir:

Bu örnekte, hesabın sahibini ve bakiyesini başlatmak için __init__ yöntemiyle bir BankAccount sınıfı tanımlıyoruz. Ayrıca hesap bakiyesi yatırma, çekme ve alma yöntemlerini de tanımlayacağız.

Oluşturulan toplam banka hesabı sayısını takip etmek için total_accounts sınıf değişkenini kullanıyoruz. __init__ yönteminde, her yeni kullanıcı hesabı oluşturulduğunda total_accounts sınıf değişkenini 1 artırıyoruz.

Daha sonra oluşturulan toplam banka hesabı sayısını döndüren get_total_accounts sınıf yöntemini tanımlıyoruz. Bu sınıf yöntemi, örnekte gösterildiği gibi sınıfın kendisi üzerinde çağrılabilir ve total_accounts sınıf değişkeninin geçerli değerini döndürür.

Ayrıca yeni BankAccount örnekleri oluşturmak için alternatif bir kurucu sağlayan create_account sınıfı yöntemini de tanımlıyoruz. Bu yöntem, sahip sınıfını ve hesap bakiyesini parametre olarak alır ve sınıfın kendisine atıfta bulunan cls parametresini kullanarak yeni bir BankAccount nesnesi oluşturur. Bu, BankAccount yapıcısını açıkça çağırmadan yeni hesaplar oluşturmamıza olanak tanır ve hesap oluşturmanın daha kolay bir yolunu sunar.

Yukarıdaki örnek için Python’daki Classmethod’u kullanarak, sınıf seviyesinde oluşturulan hesapların toplam sayısını takip edebilir ve yeni hesaplar oluşturmak için uygun bir alternatif kurucu sunarak kodumuzu daha organize ve verimli hale getirebiliriz.

Python’da statik yöntem

staticmethod, Python’da classmethod ile ilgili başka bir yöntem türüdür. Hem staticmethod hem de classmethod, sınıfın bir örneği yerine bir sınıfa ait olan yöntemleri tanımlamak için kullanılsa da, bunların bağlanma ve bunlara nasıl erişildiği konusunda farklılık gösterirler.

Sınıfın kendisini ilk parametre (cls) olarak alan Python’daki classmethod’un aksine, staticmethod herhangi bir özel ilk parametre almaz. Bunun yerine, sınıfın bir örneğini yaratmadan sınıfın kendisi içinde çağrılabilen, bir sınıfta tanımlanmış normal bir işlevdir. Python’da statik yöntem tanımının sözdizimini burada bulabilirsiniz.

class MyClass:
@staticmethod
def my_staticmethod(arg1, arg2, ...):
    # method implementation

Statik yöntemin, cls veya self gibi herhangi bir özel ilk parametreyi almaması nedeniyle örnek veya sınıf düzeyindeki özelliklere erişimi yoktur. Aslında Statik Yöntem, sınıf ad alanında kapsüllenmesi dışında, sınıf dışında tanımlanan normal bir işlev gibi davranır.

Staticmethod’un ana kullanımlarından biri, örneğin veya sınıfın durumuna bağlı olmayan bir uygulama yöntemimiz olduğu ve onu sınıfın bir örneğini oluşturmadan çağırmak istediğimiz zamandır. Bu, ortak hesaplamalar gerçekleştiren veya örneğe özgü veya sınıf düzeyindeki verilere erişim gerektirmeyen yardımcı program işlevselliği sağlayan yöntemler için yararlı olabilir.

Python’da statik yöntem örneği

Statik yöntemin sınıf yöntemine karşı kullanımını gösteren bir örnek:

class MathUtils:
    @staticmethod
    def square(n):
        return n * n

    @classmethod
    def cube(cls, n):
        return n * n * n

# Usage
print(MathUtils.square(5))  # Output: 25
print(MathUtils.cube(5))  # Output: 125

Bu örneğin çıktısı aşağıdaki gibidir:

Yukarıdaki örnekte, bir MathUtils sınıfını staticmethod square ve classmethod küpüyle tanımlıyoruz. Square yöntemi, örneğe veya sınıf durumuna bağlı olmadığından statik bir yöntem olarak tanımlanabilir. Örnekte gösterildiği gibi sınıfın kendisinde çağrılabilir.

Öte yandan küp yöntemi, sınıf düzeyindeki verilere (cls) erişim gerektirir, dolayısıyla sınıf yöntemi olarak tanımlanır. Sınıfın kendisi veya sınıfın bir örneği üzerinden çağrılabilir ve sınıfı otomatik olarak ilk parametre (cls) olarak alır ve sınıf düzeyindeki verilere erişmesine ve bunları işlemesine olanak tanır.

Özetle, Python’daki staticmethod ve classmethod’un her ikisi de bir örnek yerine bir sınıfa ait olan yöntemleri tanımlamak için kullanılır, ancak bunların bağlanma ve erişilme şekli farklılık gösterir. staticmethod, bir sınıfta tanımlanan normal bir işlevdir ve sınıfın kendisinde çağrılabilir; classmethod ise sınıfı ilk parametre (cls) olarak alır ve sınıfta veya sınıfın örneklerinde çağrılabilir.

son söz

Bu kapsamlı kılavuzda Python’daki yöntem sınıfı kavramını inceledik. Sınıf düzeyindeki özelliklere erişim, alternatif oluşturucular sağlama ve sınıf düzeyindeki işlemleri uygulama dahil olmak üzere kullanımlarını ve faydalarını tartıştık. Ayrıca Classmethod’un gerçek dünyadaki Python senaryolarında nasıl kullanılabileceğini göstermek için pratik örnekler de sağladık. Python kodumuzdaki method sınıfını kullanarak daha verimli ve düzenli nesne yönelimli programlar yazabiliriz.