Sloty to droga do zrobienia:
Pythonowym sposobem jest używanie automatów zamiast bawić się z __setter__
. Chociaż może to rozwiązać problem, nie poprawia wydajności. Atrybuty obiektów przechowywane są w " __dict__
" słowniku , dlatego można dynamicznie dodawać atrybuty do obiektów klas, które do tej pory stworzyliśmy. Używanie słownika do przechowywania atrybutów jest bardzo wygodne, ale może oznaczać stratę miejsca dla obiektów, które mają tylko niewielką liczbę zmiennych instancji.
Automaty to dobry sposób na obejście tego problemu zajmującego miejsce. Zamiast dynamicznego dyktowania, który umożliwia dynamiczne dodawanie atrybutów do obiektów, gniazda zapewniają statyczną strukturę, która zabrania dodawania atrybutów po utworzeniu instancji.
Kiedy projektujemy klasę, możemy użyć slotów, aby zapobiec dynamicznemu tworzeniu atrybutów. Aby zdefiniować gniazda, musisz zdefiniować listę z nazwą __slots__
. Lista musi zawierać wszystkie atrybuty, których chcesz użyć. Pokazujemy to w następującej klasie, w której lista slotów zawiera tylko nazwę atrybutu „val”.
class S(object):
__slots__ = ['val']
def __init__(self, v):
self.val = v
x = S(42)
print(x.val)
x.new = "not possible"
=> Nie udało się utworzyć atrybutu „nowy”:
42
Traceback (most recent call last):
File "slots_ex.py", line 12, in <module>
x.new = "not possible"
AttributeError: 'S' object has no attribute 'new'
Uwaga:
- Od Pythona 3.3 korzyść polegająca na optymalizacji wykorzystania przestrzeni nie jest już tak imponująca. W Pythonie 3.3 do przechowywania obiektów używane są słowniki współdzielenia kluczy . Atrybuty instancji mogą współdzielić między sobą część ich wewnętrznej pamięci, tj. Część, która przechowuje klucze i odpowiadające im skróty. Pomaga to zmniejszyć zużycie pamięci przez programy, które tworzą wiele wystąpień typów niewbudowanych. Ale wciąż jest sposób, aby uniknąć dynamicznie tworzonych atrybutów.
- Korzystanie ze slotów wiąże się również z kosztami własnymi. Spowoduje to przerwanie serializacji (np. Marynowanie). Spowoduje to również przerwanie dziedziczenia wielokrotnego. Klasa nie może dziedziczyć z więcej niż jednej klasy, która definiuje sloty lub ma układ instancji zdefiniowany w kodzie C (np. List, tuple lub int).
__setattr__
ale to prawdopodobnie byłoby hakerskie.