Python'da sınıf (class), nesne oluşturmak için kullanılan bir şablondur; nesne (object) ise bu şablondan üretilen gerçek örnektir. Bu makalede basit bir kütüphane projesi üzerinden Python'da sınıf ve nesne kullanımını adım adım göreceğiz: Book sınıfını tanımlayacak, ondan kitap nesneleri oluşturacak ve bu nesneleri bir Library sınıfıyla yöneteceğiz. Amaç, sınıf ve nesne kavramlarını soyut tanımlarla değil, çalışan bir kod örneğiyle somutlaştırmak.
Sınıf ve Nesne Arasındaki Fark Nedir?
Sınıf, bir nesnenin hangi özelliklere (attribute) ve hangi davranışlara (metot) sahip olacağını tanımlayan bir taslaktır. Nesne ise bu taslaktan türetilen, kendine ait verileri taşıyan gerçek bir varlıktır. Bu ayrımı somutlaştırmak için bir Book sınıfı düşünelim:
class Book:
pass
Burada Book bir sınıftır; henüz herhangi bir kitabı temsil etmez, sadece "kitap nedir" sorusuna cevap veren bir kalıptır. Bu sınıftan bir nesne oluşturduğumuzda durum değişir:
kitap1 = Book()
kitap2 = Book()
kitap1 ve kitap2, aynı sınıftan üretilmiş iki farklı nesnedir. İkisi de Book şablonunu paylaşır ama bellekte ayrı ayrı yer tutar ve ileride göreceğimiz gibi birbirinden farklı veriler taşıyabilir. Sınıfı bir kalıp, nesneyi ise bu kalıptan çıkan her bir ürün gibi düşünebilirsiniz: kalıp tektir, ürün sayısı ise ihtiyaç kadardır.
class Tanımı ve __init__ Metodu
Gerçek bir kütüphane projesinde her kitabın başlığı, yazarı gibi bilgileri olması gerekir. Bu bilgileri nesne oluşturulur oluşturulmaz atamak için __init__ metodu kullanılır. __init__, bir sınıftan nesne üretildiği anda otomatik çalışan özel bir metottur:
class Book:
def __init__(self, title, author):
self.title = title
self.author = author
Burada self parametresi, o an oluşturulmakta olan nesnenin kendisini temsil eder. Python, bir metodu çağırdığınızda ilgili nesneyi otomatik olarak self üzerinden geçirir; bu yüzden metot tanımlarken self parametresini elle yazmanız gerekir, ama metodu çağırırken bunu belirtmenize gerek yoktur. Nesne oluşturmak artık şu şekilde işler:
kitap1 = Book("Suç ve Ceza", "Dostoyevski")
Bu satır çalıştığında Python arka planda __init__ metodunu çağırır ve title, author değerlerini kitap1 nesnesine bağlar. Bu örnek, Python 3'teki temel sınıf ve nesne oluşturma sözdizimini kullanır.
Örnek Özellikleri ve Metotlar
self.title ve self.author gibi ifadeler, örnek özelliği (instance attribute) olarak adlandırılır; her nesneye özel olarak saklanan verilerdir. Kütüphane projemizde bir kitabın ödünç alınıp alınmadığını takip etmek için bu özelliklerden birini daha ekleyelim ve davranışları metotlarla tanımlayalım:
class Book:
def __init__(self, title, author):
self.title = title
self.author = author
self.is_borrowed = False
def borrow(self):
if self.is_borrowed:
print(f"'{self.title}' zaten ödünç alınmış.")
else:
self.is_borrowed = True
print(f"'{self.title}' ödünç alındı.")
def return_book(self):
self.is_borrowed = False
print(f"'{self.title}' iade edildi.")
is_borrowed özelliği her kitap nesnesi için ayrı ayrı tutulur, yani bir kitabın ödünç durumu diğerini etkilemez. borrow ve return_book metotları da self üzerinden bu duruma erişip günceller. Böylece her Book nesnesi kendi verisini ve kendi davranışını bir arada taşır; bu da nesne yönelimli programlamanın temel mantığıdır.
Library Sınıfıyla Nesneleri Yönetmek
Tek bir Book nesnesiyle çalışmak yeterli değil, gerçek bir kütüphanede onlarca kitabı yönetmemiz gerekir. Bunun için kitapları bir arada tutan ve üzerlerinde işlem yapan bir Library sınıfı tanımlayalım:
class Library:
def __init__(self):
self.books = []
def add_book(self, book):
self.books.append(book)
print(f"'{book.title}' kütüphaneye eklendi.")
def is_available(self, title):
for book in self.books:
if book.title == title:
return not book.is_borrowed
print(f"'{title}' kütüphanede bulunamadı.")
return False
__init__ metodunda self.books adında boş bir liste oluşturuyoruz. Bu liste, Library nesnesine ait olan ve içine Book nesnelerini koyacağımız yer. add_book metodu parametre olarak bir Book nesnesi alır ve listeye ekler. Burada önemli olan nokta: listeye string veya sözlük değil, doğrudan nesne ekliyoruz. Bu sayede her kitabın kendi borrow() ve return_book() metotlarına listenin içinden de erişebiliyoruz.
is_available metodu ise verilen başlığa göre listede dolaşır (for book in self.books), eşleşen kitabı bulur ve is_borrowed özelliğinin tersini döndürür. Kitap bulunamazsa False döner ve kullanıcıyı bilgilendirir. Bu, nesne listeleri üzerinde arama yapmanın tipik bir örneğidir ve gerçek projelerde veritabanı sorguları yerine geçici çözüm olarak sık kullanılır.
Tam Kod ve Beklenen Çıktı
Şimdi Book ve Library sınıflarını birleştirip projeyi çalıştıralım:
class Book:
def __init__(self, title, author):
self.title = title
self.author = author
self.is_borrowed = False
def borrow(self):
if not self.is_borrowed:
self.is_borrowed = True
print(f"'{self.title}' ödünç alındı.")
else:
print(f"'{self.title}' zaten ödünçte.")
def return_book(self):
self.is_borrowed = False
print(f"'{self.title}' geri getirildi.")
class Library:
def __init__(self):
self.books = []
def add_book(self, book):
self.books.append(book)
print(f"'{book.title}' kütüphaneye eklendi.")
def is_available(self, title):
for book in self.books:
if book.title == title:
return not book.is_borrowed
print(f"'{title}' kütüphanede bulunamadı.")
return False
library = Library()
book1 = Book("Simyacı", "Paulo Coelho")
library.add_book(book1)
print(library.is_available("Simyacı"))
book1.borrow()
print(library.is_available("Simyacı"))
'Simyacı' kütüphaneye eklendi.
True
'Simyacı' ödünç alındı.
False
İlk satır add_book çağrısından gelir. is_available("Simyacı") ilk çağrıldığında kitap henüz ödünç alınmadığı için True döner. book1.borrow() çağrısı kitabın durumunu değiştirir ve ekrana bilgi yazar. İkinci is_available çağrısında ise is_borrowed artık True olduğu için sonuç False olur. Burada dikkat edilmesi gereken nokta, library.books listesindeki nesnenin ve book1 değişkeninin aynı nesneyi işaret etmesi; birini değiştirdiğimizde diğerinden de bu değişikliği görürüz.
Sırada Ne Var: Kalıtım
Book sınıfı basit bir kitabı temsil ediyor ama gerçek kütüphanelerde e-kitaplar, sesli kitaplar gibi farklı türler de olabilir. Bunların hepsi için sıfırdan sınıf yazmak yerine, ortak özellikleri Booktan miras alan yeni sınıflar tanımlayabiliriz:
class EBook(Book):
def __init__(self, title, author, file_size):
super().__init__(title, author)
self.file_size = file_size
Burada EBook, Book sınıfının tüm özelliklerini (title, author, is_borrowed) ve metotlarını (borrow, return_book) devralır, üstüne file_size gibi kendine özgü bir özellik ekler. Bu konuya, yani kalıtım (inheritance) kavramına bir sonraki bölümde daha detaylı gireceğiz.
Sıkça Sorulan Sorular
Python'da sınıf ile nesne arasındaki temel fark nedir?
Sınıf, bir nesnenin nasıl görüneceğini ve nasıl davranacağını tanımlayan bir şablondur. Örneğin Book sınıfı, her kitapta hangi bilgilerin (başlık, yazar, yıl) bulunacağını ve bu kitapla hangi işlemlerin yapılabileceğini belirler. Nesne ise bu şablondan üretilen gerçek örnektir; her nesne kendi verisini taşır. Yani sınıf tariftir, nesne o tarife göre pişirilen yemektir.
self parametresi neden zorunludur?
Python, bir metot çağrıldığında bu metodun hangi nesne üzerinde çalıştığını bilmek zorundadır. self, işte bu bilgiyi taşır: metodun içinde self.title dediğinizde, "bu belirli nesnenin title özelliği" demiş olursunuz. self olmadan Python, aynı sınıftan üretilmiş birden fazla nesnenin verilerini birbirinden ayıramaz.
__init__ metodu her sınıfta olmak zorunda mı?
Hayır, zorunlu değildir. Eğer sınıfınızın nesneleri oluşturulurken herhangi bir başlangıç verisine ihtiyacı yoksa __init__ yazmayabilirsiniz; Python bu durumda varsayılan boş bir kurucu kullanır. Ancak pratikte nesnelerin genellikle bir başlangıç durumu olur (bir kitabın başlığı, bir kullanıcının adı gibi), bu yüzden __init__ neredeyse her sınıfta karşınıza çıkar.
Bir sınıftan birden fazla nesne nasıl oluşturulur ve yönetilir?
Aynı sınıfı istediğiniz kadar çağırarak birbirinden bağımsız nesneler oluşturabilirsiniz; her biri kendi verisini taşır. Bu nesneleri tek tek değişkenlerde tutmak yerine, örnekte gördüğümüz Library sınıfı gibi bir liste veya sözlük içinde saklamak daha pratiktir. Bu sayede nesneleri toplu halde ekleyebilir, arayabilir ve üzerlerinde döngüyle işlem yapabilirsiniz.
Bu sorularla birlikte sınıf ve nesne mantığının temel taşları netleşmiş oldu; artık kendi projelerinizde benzer yapıları rahatlıkla kurabilirsiniz.
Sık Sorulan Sorular
Python'da sınıf ile nesne arasındaki temel fark nedir?
Sınıf, nesnelerin nasıl görüneceğini ve nasıl davranacağını tanımlayan bir şablondur; içinde veri (öznitelik) ve davranış (metot) tanımları bulunur ama kendisi bir varlık değildir. Nesne ise bu şablondan üretilen, bellekte gerçek bir yer kaplayan somut örnektir. Örneğin "Kitap" bir sınıfsa, "Suç ve Ceza" adlı belirli bir kitap nesnesidir. Aynı sınıftan istediğiniz kadar farklı nesne oluşturabilirsiniz.
self parametresi neden zorunludur?
self, bir metodun hangi nesne üzerinde çalıştığını Python'a bildiren referanstır. Python, metotları çağırırken nesneyi otomatik olarak ilk parametre olarak gönderir; bu sayede metot içinde o nesneye ait öznitelik ve metotlara erişebilirsiniz. self olmadan Python, aynı sınıftan üretilmiş farklı nesnelerin verilerini birbirinden ayırt edemez. İsim olarak "self" bir kural değil, yaygın bir gelenektir ama değiştirmemek okunabilirlik için önemlidir.
__init__ metodu her sınıfta olmak zorunda mı?
Hayır, zorunlu değildir. __init__ tanımlanmazsa Python varsayılan olarak boş bir yapıcı kullanır ve nesne özniteliksiz oluşturulur. Ancak nesne oluşturulurken başlangıç değerleri atamak istiyorsanız __init__ tanımlamak pratik ve yaygın bir yaklaşımdır. Özellikle her nesnenin isim, yaş veya ID gibi kendine özgü verilere ihtiyaç duyduğu durumlarda __init__ metodu bu değerleri parametre olarak alıp nesneye atamak için kullanılır.
Bir sınıftan birden fazla nesne nasıl oluşturulur ve yönetilir?
Aynı sınıf tanımını kullanarak istediğiniz kadar nesne örneği yaratabilirsiniz; her biri bağımsız bellek alanına ve kendi özniteliklerine sahip olur. Bu nesneleri bir listede veya sözlükte tutmak, yönetimi kolaylaştırır. Örneğin bir kütüphane projesinde her kitabı bir nesne olarak oluşturup hepsini bir listeye ekleyebilir, ardından döngüyle listedeki nesneler üzerinde işlem yapabilirsiniz. Bu yaklaşım, çok sayıda benzer veriyi düzenli yönetmenin temelini oluşturur.
Sınıf ve nesne mantığını küçük bir kütüphane projesiyle uygulamalı görmek, Python'daki nesne yönelimli programlamanın temellerini pekiştirmenin en etkili yollarından biridir. Konuyu daha da ilerletmek isterseniz Python'da kalıtım (inheritance) kullanımı hakkındaki rehberimize göz atabilirsiniz.