Atribut slot dalam Python adalah alat yang digunakan untuk mengisytiharkan sifat -sifat data secara jelas (pembolehubah contoh) di peringkat kelas, yang boleh membawa kepada penggunaan memori yang lebih efisien dan akses atribut yang lebih cepat. Apabila kelas mentakrifkan atribut __slots__
, Python mencipta pelbagai saiz tetap kecil untuk setiap contoh kelas, bukannya menggunakan kamus dinamik untuk menyimpan atribut contoh. Mekanisme ini berfungsi beberapa tujuan:
__slots__
, __dict__
contoh tidak dibuat, yang menjimatkan ingatan, terutama ketika berurusan dengan sejumlah besar contoh.__slots__
boleh lebih cepat daripada mengakses atribut dalam contoh berasaskan kamus standard, kerana ia mengelakkan overhead carian kamus.__slots__
ditakrifkan, Python mengehadkan penciptaan sifat -sifat baru dalam keadaan kepada yang ditakrifkan dalam __slots__
, kecuali __dict__
secara eksplisit dimasukkan ke dalam __slots__
. Inilah contoh asas cara menggunakan __slots__
:
<code class="python">class Point: __slots__ = ('x', 'y') def __init__(self, x, y): self.x = x self.y = y</code>
Penggunaan __slots__
dapat memberikan beberapa manfaat prestasi:
__slots__
menggantikan __dict__
contoh dengan array bersaiz tetap, ia dapat mengurangkan jejak memori keadaan. Ini amat bermanfaat apabila membuat sejumlah besar contoh.__slots__
boleh diakses lebih cepat daripada yang disimpan dalam kamus. Ini kerana mengakses elemen dalam pelbagai saiz tetap kecil biasanya lebih cepat daripada melakukan pencarian kamus.__slots__
boleh dikumpulkan dengan lebih cepat oleh pemungut sampah kerana terdapat rujukan yang lebih sedikit untuk diikuti.Untuk menggambarkan manfaat ini, pertimbangkan contoh berikut:
<code class="python">import sys class StandardPoint: def __init__(self, x, y): self.x = x self.y = y class SlotPoint: __slots__ = ('x', 'y') def __init__(self, x, y): self.x = x self.y = y standard = StandardPoint(1, 2) slot = SlotPoint(1, 2) print(sys.getsizeof(standard)) # Output may be around 56 bytes print(sys.getsizeof(slot)) # Output may be around 32 bytes</code>
Dalam contoh ini, contoh SlotPoint
menggunakan memori yang kurang daripada contoh StandardPoint
.
Menggunakan __slots__
Impak tugasan atribut dengan cara berikut:
__slots__
ditakrifkan, hanya atribut yang disenaraikan dalam __slots__
boleh diberikan kepada suatu contoh. Percubaan untuk menetapkan atribut yang tidak berada di __slots__
akan menaikkan AttributeError
, kecuali __dict__
dimasukkan ke dalam __slots__
.__dict__
automatik : Secara lalai, contoh kelas dengan __slots__
tidak mempunyai __dict__
. Ini bermakna tugasan atribut dinamik dilumpuhkan melainkan __dict__
secara eksplisit dimasukkan ke dalam __slots__
.__weakref__
: Jika kelas perlu menyokong rujukan yang lemah, __weakref__
mesti dimasukkan ke dalam __slots__
.Inilah contoh untuk menunjukkan kesan ini:
<code class="python">class RestrictedPoint: __slots__ = ('x', 'y') point = RestrictedPoint() point.x = 10 # This is allowed point.y = 20 # This is allowed try: point.z = 30 # This will raise an AttributeError except AttributeError as e: print(e) # Output: 'RestrictedPoint' object has no attribute 'z'</code>
Ya, __slots__
boleh digunakan dalam kombinasi dengan warisan, tetapi ada beberapa pertimbangan yang harus diingat:
__slots__
, ia akan mewarisi slot dari superclassnya, tetapi hanya jika superclass juga mentakrifkan __slots__
. Jika superclass tidak menggunakan __slots__
, keadaannya masih akan menggunakan __dict__
, yang boleh menyebabkan ketidakcekapan ingatan.__dict__
: Jika subclass mahu membenarkan atribut dinamik, ia boleh termasuk __dict__
dalam __slots__
. Walau bagaimanapun, ini boleh mengalahkan tujuan penjimatan ingatan menggunakan __slots__
di tempat pertama.__slots__
, semua kelas mestilah menentukan __slots__
atau mewarisi dari kelas yang mentakrifkan __slots__
. Jika satu kelas induk tidak menggunakan __slots__
, contoh subclass masih akan mempunyai __dict__
.Berikut adalah contoh untuk menggambarkan pertimbangan ini:
<code class="python">class Base: __slots__ = ('x',) class Derived(Base): __slots__ = ('y',) # Inherits 'x' from Base derived = Derived() derived.x = 10 # Inherited from Base derived.y = 20 # Defined in Derived class FlexibleDerived(Base): __slots__ = ('y', '__dict__') # Allows dynamic attributes flexible = FlexibleDerived() flexible.x = 10 # Inherited from Base flexible.y = 20 # Defined in FlexibleDerived flexible.z = 30 # Dynamic attribute, allowed because of __dict__</code>
Kesimpulannya, sementara __slots__
boleh digunakan dengan berkesan dengan warisan, ia memerlukan perancangan yang teliti untuk memastikan pengoptimuman memori yang dikehendaki dan tingkah laku atribut dicapai di seluruh hierarki kelas.
Atas ialah kandungan terperinci Terangkan tujuan atribut __slots__.. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!