ProgramlamaBackend Python Geliştirici

Python sınıflarında __slots__ nedir, neden gereklidir ve sınırlamaları nelerdir?

Hintsage yapay zeka asistanı ile mülakatları geçin

Cevap.

__slots__ — bir sınıfın özel bir niteliği olup, örneğin izin verilen niteliklerin kümesini kısıtlar, bellek tasarrufu sağlar ve niteliklere erişimi hızlandırır. __slots__ kullanımı, birçok benzer nesne için özellikle geçerlidir.

Konuya giriş:

__slots__'ın ortaya çıkması, her Python nesnesinin varsayılan olarak bir nitelik sözlüğüne (__dict__) sahip olmasından kaynaklanmaktadır; bu kullanışlıdır ancak bellek açısından maliyetlidir. Küçük bir nitelik setine sahip bir milyon nesne için önemli bir ek yük meydana gelir.

Sorun:

Normal bir sınıfın örnekleri dinamik olarak genişletilebilir; bu kullanışlıdır, ancak verimsizdir. __slots__ kullanmak, yeni niteliklerin dinamik olarak eklenmesini kısıtlar, örneklik niteliğini kaldırır, bellek tasarrufu sağlar ve erişimi hızlandırır.

Çözüm:

İzin verilen alanların listesini __slots__ niteliğinde belirtin:

class Point: __slots__ = ('x', 'y') def __init__(self, x, y): self.x = x self.y = y p = Point(1, 2) p.z = 3 # AttributeError: 'Point' nesnesinin 'z' niteliği yok

Anahtar özellikler:

  • dict ve varsayılan olarak weakref'in yokluğundan dolayı bellek tasarrufu sağlar.
  • İzin verilen niteliklerin katı bir kümesini tanımlar.
  • Niteliklere erişimi, önceden ayrılmış slotlar sayesinde hızlandırır (dict içinde arama yapmayı gerektirmez).

Kandırmaca sorular.

slots ile bir sınıf örneği oluşturmaya çalışırken liste dışı bir nitelik eklenebilir mi?

Hayır. __slots__ listesinde olmayan bir niteliği eklemeye çalıştığınızda AttributeError hatası fırlatılacaktır. Bu, nesnenin genişletilebilirliği üzerinde kısıtlamalar getirir.

slots olan bir sınıftan miras alınabilir mi ve yeni alanlar eklenebilir mi?

Evet, ancak her miras alan sınıf kendi __slots__'ını tanımlamalıdır. Bu durumda, ebeveyn ve mevcut __slots__ birleştirilir. Ancak, miras alandaki __slots__ tanımlanmazsa, çocuk nesne tekrar bir __dict__'e sahip olacaktır!

Immutable (değişmez) türler için slots çalışır mı?

Evet, ancak slot nesnesinin değişmez olmasını sağlamak için ek önlemler almak gerekir (örneğin, setter olmadan property aracılığıyla).

Tipik hatalar ve anti-patternler

  • Alt sınıfa slots tanımlamamak, bellek verimliliğini bozmak.
  • Çoklu mirasın varlığında slots ile çalışmasını beklemek — çakışmalar ve hatalar ortaya çıkabilir.
  • Slotları standart anlamda seri hale getirmeye çalışmak bazen zordur (örneğin, pickle dict gerektirir).

Gerçek hayattan örnek

Olumsuz durum

Bir nokta için normal sınıf:

class Point: def __init__(self, x, y): self.x = x self.y = y points = [Point(i, i) for i in range(1_000_000)]

Artıları:

  • Esnek — her türlü niteliği eklemek mümkündür.
  • Yeni başlayanlar için anlaşılır.

Eksileri:

  • Görev yöneticisi, bellek tüketiminde dikkate değer bir artış gösteriyor (yaklaşık +%20-30).

Olumlu durum

Benzer sınıf ancak slotlar ile:

class Point: __slots__ = ('x', 'y') def __init__(self, x, y): self.x = x self.y = y points = [Point(i, i) for i in range(1_000_000)]

Artıları:

  • Milyonlarca nesnede %30'a kadar bellek tasarrufu.
  • Alanlara erişim daha hızlı.

Eksileri:

  • Nesneler esnek olmaktan çıkıyor: yeni nitelikleri anında eklemek mümkün değil.