@dataclass dekoratörü, Python 3.7'de tanıtılan veri saklama sınıflarının oluşturulmasında şablon kodunu azaltmak için kullanılan bir araçtır. Python, tür ipuçları sayesinde otomatik olarak __init__, __repr__, __eq__ gibi metodları oluşturur.
Konu Tarihi:
dataclass'ın ortaya çıkmasından önce, geliştiriciler manuel olarak şablon sınıfları yazar, yapıcılar, karşılaştırma metodları ve repr'ı uygularlardı. Daha sonra genellikle adlandırılmış demetlere veya attrs gibi kütüphanelere geçerlerdi. @dataclass'ın getirilmesi bu süreci standartlaştırmış ve basitleştirmiştir.
Sorun:
Şablon kod (boilerplate), yapıcılar ve karşılaştırma metodları arasında kod tekrarları, genellikle hatalara yol açar ve büyük uygulamaların bakımını zorlaştırır.
Çözüm:
Tür ipuçlarını ve özel @dataclass dekoratörünü kullanarak sınıfta gereken tüm metodları otomatik olarak oluşturmak mümkündür.
Kod örneği:
from dataclasses import dataclass @dataclass class Point: x: int y: int p1 = Point(10, 20) p2 = Point(10, 20) print(p1 == p2) # True, otomatik olarak oluşturulmuş __eq__ print(p1) # Point(x=10, y=20), otomatik olarak oluşturulmuş __repr__
Anahtar özellikler:
@dataclass, kalıtım davranışını değiştirir mi (kalıtım ile ilgili özellikler)?
Evet. dataclass'lı sınıfların kalıtımında özel bir dikkat gereklidir: üst sınıf alanları, alt sınıf alanlarından önce gelir ve ayrıca yapıcılar / argüman sırası çakışmalarında hatalar çıkabilir. Üst ve alt sınıflarda aynı isimli alanlar varsa, sonuncusu önceki alanı geçersiz kılar.
dataclass'ta varsayılan değiştirilebilir değerler kullanmak mümkün mü?
Hayır, bu nesneleri (örneğin, liste) varsayılan olarak doğrudan kullanmak mümkün değildir — field(default_factory=list) kullanmak gerekir. Aksi takdirde, sınıfın tüm örnekleri aynı koleksiyonu paylaşır.
Örnek:
from dataclasses import dataclass, field @dataclass class User: values: list = field(default_factory=list)
@dataclass, her senaryo için hızlı mıdır? Büyük veri dizilerini saklamak için uygun mudur?
Hayır. dataclass, bellek optimizasyonu için en verimli seçenek değildir. Milyonlarca nesne depolamak için __slots__, namedtuple veya özel yapılar kullanmak daha iyidir — dataclass yardımcı alanlar eklediği için bellek tasarrufu sağlamaz. slots=True parametresini belirterek kombinlemek mümkündür (Python 3.10+), veya el ile slots kullanabilirsiniz.
@dataclass class Cart: items: list = [] # hata! c1 = Cart() c2 = Cart() c1.items.append("a") print(c2.items) # ['a'] — tüm Cart aynı listeyi paylaşıyor
Artılar:
Eksiler:
from dataclasses import dataclass, field @dataclass class Cart: items: list = field(default_factory=list) c1 = Cart() c2 = Cart() c1.items.append("a") print(c2.items) # []
Artılar:
Eksiler:
field(default_factory=...) hakkında bilgi sahibi olmak gerekir (bu ayrı bir öğrenim gerektirir).