Open bufgix opened 4 years ago
Great
hey
, Nice
function ReactionsBar({ reactionsData }) {
const [reactions, setReactions] = React.useState({});
const prepareReactions = () => {
let reactions = {
THUMBS_DOWN: { content: "👎", count: 0, names: [] },
THUMBS_UP: { content: "👍", count: 0, names: [] },
HEART: { content: "❤️", count: 0, names: [] },
HOORAY: { content: "🎉", count: 0, names: [] },
LAUGH: { content: "🤣", count: 0, names: [] },
ROCKET: { content: "🚀", count: 0, names: [] },
CONFUSED: { content: "😕", count: 0, names: [] },
EYES: { content: "👀", count: 0, names: [] },
TOTAL_COUNT: reactionsData.totalCount
};
if (reactions.TOTAL_COUNT) {
reactionsData.nodes.forEach(reaction => {
reactions[reaction.content].count += 1;
reactions[reaction.content].names.push(reaction.user.login);
});
}
...
Nedir?
Python 3.7 ile gelen güzel bir yapı olan
dataclass
'lar, Python geliştiricileri için mükemmel bir yenilik. Bu yazıda elimden geldiğince bu yapıyı anlatmaya çalısacağım.Efendim
dataclass
'lar normal class'lardaki kendini sürekli tekrarlayan kodları yazmayı engelleyen, içinde (genelde) veri depolayan classlardır. Aşağıdaki örnekte birdataclass
'ın nasıl tanımladığını görebilirsiniz.Görüldüğü gibi
dataclass
'lar@dataclass
decoratoru ile tanımlanır.Bir
dataclass
, bazı special method'ları sizin için değiştirir. Mesela__str__()
methodu otomatik olarak sınıf içindeki değerleri bastıracaktır.Eğer biz böyle bir çıktı isteseydik şöyle bir şey yazmamız gerekirdi;
Görüldüğü gibi bir değişkeni
__init__
'den alıp nesne değişkeni yapmak için 3 kere yazmamız gerekiyor.Ayrıca dikkatli bakarsanız objelerin tam olarak tanımlanmadığını göreceksiniz.
Bunun nedeni
dataclass
'ların__eq__
methodunu override etmiş olmaları. Normalde Python, obje karşılaştırma yaparken objelerin adreslerini karşılaştırır amadataclass
'lar sınıf içindeki değerleri karşılaştırır. Eğer bunu kendiniz yazmak isteseydiniz;dataclass
'lar bunu bizim için yapar.dataclass
'lara default değerler de verebiliriz;Şu ana kadar hiç fonksiyon yazmadık ama
dataclass
'da fonksiyon yazmak ile normalde yazmak arasında hiç fark yoktur.Biraz
@dataclass
decoratoru hakkında konuşalım.@dataclass
decoratoru birçok parametre alabilir.init
: eğerTrue
ise__init__
fonksiyonunu override eder.repr
: eğerTrue
ise__repr__
fonksiyonunu override eder.eq
: eğerTrue
ise__eq__
fonksiyonunu override eder. Bu konuya yukarda değinmiştik.order
: eğerTrue
ise (varsayılanFalse
)__lt__
,__le__
,__gt__
ve__ge__
fonksiyları override eder. Bu fonksiyonlar karşılaştırma fonksiyonlarıdır.dataclass
,__eq__
'de olduğu gibi class değerlerini karşılaştırır.frozen
: eğerTrue
ise nesne oluşturduktan sonra gelen değer atamalarıFrozenInstanceError
hatasını raise edecektir.dataclass
ile kalıtım da yapabiliriz.Alternatifler
dataclass
'ların (genellikle) veri depoladığını söylemiştik. Bunu Python'da sadecedataclass
'ların yapmadığını görmüşsünüzdür. Basit veri yapıları olantuple
vedict
de veri depolar.Ama dikkat ederseniz
dataclass
'lar kadar kullanışlı olmadığını görürsünüz. Meselatuple
'de argumanların yerlerini karıştırabilirsiniz debug ederken bu işinizi çok zorlaştır.dict
de ise dataya erişmek için mutlaka birkey
'e ihtiyaç vardır.Tabi bunun ne kadar zahmetli olduğunu görüyorsunuz. Ama durun yukarıdaki kodun daha iyisini yapan bir veri yapısı var zaten.
namedtuple
E
dataclass
'lardan farkı ne bunun? Öncelikledataclass
'ların çok daha fazla özelliği buluyor. Yukarıda anlattığım kalıtım ve fonksiyon ekleme işlemlerinamedtuple
'de çok daha zor. Öte yandan karşılaştırma yaparkennamedtuple
istediğinizi vermeyecektir. Yukarıdaki örnekten devam edelimİyi bir şey gibi gözükse de sonuçta kendi türünde olmadığını zannettiğimiz objelerle tam anlamıyla doğru karşılaştırmalar vermiyor.
Ayırca
namedtuple
obje oluştuktan sonra verilerin değişmesine izin vermeyecektir.field()
Bir seneryo üzerinden devam edelim.
Buradan yeni nesneler üretelim
Şimdi
Lesson
sınıfına default deger vermeyi deneyelim. Bunu yaparken bir factory fonksiyon yazalım.Teoride
Lesson
a varsayılan değer vermek için şöyle yaparsınız.Böyle bir tanım Python'ın en büyük anti-pattern'lerinden birisidir: Varsayılan olarak değişken değer kullanmak. Buradaki problem şu ki
Lesson
'nun tüm versiyonları aynı.students
'in varsayılan liste objesini kullanacak. Kısacası birLesson
'dan herhangi birStudent
silindiği vakitLesson
'nun tüm versiyonlarından da silinecek. Aslına bakarsanız dataclass'lar bunun olmasının önüne geçip size ValueError döndürüyor.Bunun önüne geçmek için
field
methodunundefault_factory
diye bir parametresi var.field
, sadecedefault_factory
ile sınırlı değil. Bu bağlantıdan diğer parametrelere ve ne işe yaradıklarına ulaşabilirsiniz.Optimizasyon
Bahsedeceğim şey
__slots__
,__slots__
kısaca, sınıflara dinamik olmayan sabit attributelar belirleyerek RAM'dan ve hızdan tasarruf sağlıyor.__slots__
, kendi başına ele alınması gereken bir konu oluğu için şuradan daha fazla bilgiye ulaşabilirsiniz.dataclass
'larda__slots__
kullanımı normal classlardaki gibidir.Hafızada sahip olduğu büyüklüğe bakalım.
Ayırca Python'un veriye erişmesi de normal class'lara göre daha hızlıdır.
tabi yazmış olduğumuz sınıfın basitliğinden dolayı aradaki fark oldukça az. Daha büyük sınıflarda bu fark dikkate değer biçimde artıyor.