Python Programmeringsstudio.

& Raquo; Python Object Oriented Programmering.

Instans Slots.

Ved a tildele en sekvens av strengattributtnavn til et special_slots_class-attributt, er det mulig for en ny stilklasse a begrense settet med juridiske attributter som forekomster av klassen vil ha og optimalisere minne og hastighetsytelse.

Denne spesielle attributtet settes vanligvis ved a tilordne en sekvens av strengnavn til variabelen__slots_ pa overste niva i en klassesetning: bare de navnene i.

_slots_list kan tilordnes som forekomstattributter. Likevel, som alle navn i Python, ma forekomstnavn fortsatt tildeles for de kan refereres, selv om de er listet in_slots__. For eksempel:

AttributeError: ‘limiter’ -objektet har ingen attributt ‘ape

Slots er noe av en pause med Pythons dynamiske natur, noe som dikterer at noe navn kan opprettes ved oppdrag. Imidlertid er denne funksjonen tenkt som bade en mate a fange «skrivefeil» pa feil som dette (oppdrag til ulovlige attributtnavn ikke inne.

_slots_are oppdaget), samt en optimaliseringsmekanisme. A tildele en navneordliste for hvert forekomstobjekt kan bli dyrt nar det gjelder minne hvis mange forekomster er opprettet, og bare noen fa attributter er pakrevd. For a spare plass og hastighet kjoring (i en grad som kan variere per program), i stedet for a tilordne en ordbok for hver forekomst, lagres sporattributter sekvensielt for raskere oppslag.

Slots og generisk kode.

Faktisk kan noen tilfeller med spor ikke ha a_dict_attribute ordbok i det hele tatt, noe som kan gjore noen metaprogrammer mer komplekse (inkludert noen kodet i denne boken). Verktoy som generisk viser attributter eller tilgangsattributter med strengenavn, ma for eksempel v re forsiktig med a bruke flere lagringsneutrale verktoy than_dict__, for eksempel funksjonene getattr, setattr og dir, som gjelder for attributter basert pa enten.

_dict_or_slots_storage. I noen tilfeller ma begge attributtkilder kanskje bli forespurt for fullstendighet.

For eksempel, nar spor brukes, har forekomster normalt ikke en attributtordbok-Python bruker klassebeskrivelsesfunksjonen dekket i kapittel 37 for a allokere plass for sporattributter i forekomsten i stedet. Bare navn pa sporlisten kan tilordnes forekomster, men sporbaserte attributter kan fortsatt hentes og settes etter navn ved hjelp av generiske verktoy. I Python 3.0 (og i 2.6 for klasser avledet fra objekt): & gt; & gt; & gt; klasse C:

. _slots_ = [‘a’, ‘b’] #_slots_means no_dict_by default.

AttributeError: ‘C’ -objektet har ingen attributt ‘_dict_’

& Gt; & gt; & gt; setattr (X, ‘b’, 2) # Men getattr () og setattr () jobber fortsatt.

& Gt; & gt; & gt; ‘a’ i dir (X) # Og dir () finner ogsa slot-attributter.

Uten en attributt navnerom-ordbok, er det ikke mulig a tildele nye navn til forekomster som ikke er navn i sporlisten: & gt; & gt; & gt; klasse D:

. def _init_ (selv): self.d = 4 # Kan ikke legge til nye navn hvis no_dict_.

AttributeError: ‘D’ -objektet har ingen attributt ‘d’

Imidlertid kan ekstra attributter fortsatt bli innkvartert ved a inkludere __dict__ i.

_slots_, for a tillate en attributt namespace dictionary. I dette tilfellet brukes begge lagringsmekanismer, men generiske verktoy som getattr tillater oss a behandle dem som et enkelt sett med attributter: & gt; & gt; & gt; klasse D:

. _slots_ = [‘a’, ‘b’, ‘_dict_’] # List_dict_to inkludere en ogsa.

. c = 3 # Klasse attrs jobber normalt. def _init_ (selv): self.d = 4 # d put in_dict_, a in_slots_.

& Gt; & gt; & gt; X._dict __ # Noen objekter har both_dict_and_slots_.

& Gt; & gt; & gt; X.a # All forekomst er udefinert til tildelt.

Kode som onsker a liste alle forekomstegenskaper generisk, kan likevel fortsatt tillate bade lagringsskjemaer, siden dir returnerer ogsa arvede attributter (dette avhenger av ordliste iteratorer for a samle nokler):

& Gt; & gt; & gt; for attr i liste (X .__ dict__) + X .__ slots__:. skriv ut (attr, ‘= & gt;’, getattr (X, attr))

Siden enten kan utelates, er dette mer korrekt kodet som folger (getattr tillater standard):

& Gt; & gt; & gt; for attr i liste (getattr (X, ‘__dict__’, [])) + getattr (X, ‘__slots__’, []):. skriv ut (attr, ‘= & gt;’, getattr (X, attr))

Multiple_slot_lists i superclasses.

V r imidlertid oppmerksom pa at denne koden kun adresserer spornavnene i lowest_slots_attribute arvet av en forekomst. Hvis flere klasser i et klassetre har sin egen.

_slots_attributes, generiske programmer ma utvikle andre retningslinjer for oppforing av attributter.

(for eksempel klassifisering av spornavn som attributter til klasser, ikke tilfeller).

Slotdeklarasjoner kan vises i flere klasser i et klassetre, men de er underlagt en rekke begrensninger som er noe vanskelig a rationalisere med mindre du forstar implementeringen av slots som klasseniva deskriptorer (et verktoy vi vil studere i detalj i siste del av denne boken):

� Hvis en underklasse arver fra en superklasse uten a_slots_, vil superklassens__dict_attribute alltid v re tilgjengelig, noe som gjor a_slots_in underklassen meningslos.

� Hvis en klasse definerer det samme spornavnet som en superklasse, vil versjonen av navnet definert av superklasse-sporet kun v re tilgjengelig ved a hente sin deskriptor direkte fra superklassen.

� Fordi betydningen av a__slots_declaration er begrenset til klassen der den vises, vil underklasser ha a__dict_unless de definerer ogsa a__slots_.

Nar det gjelder a oppgi forekomstattributter generisk, kan spor i flere klasser kreve manuell klassestromklatring, dir-bruk eller en policy som behandler spornavn som en annen kategori av navn i det hele tatt: & gt; & gt; & gt; klasse E:

. _slots_ = [‘a’, ‘_dict_’] # Det gjor ogsa sin underklasse.

& Gt; & gt; & gt; X.a = 1; X.b = 2; X.c = 3 # Eksemplet er foreningen.

# Men slots er ikke sammenfoyde.

# Instans arver * laveste * _slots_.

# Og har sin egen en attr dikt.

& Gt; & gt; & gt; for attr i liste (getattr (X, ‘__dict__’, [])) + getattr (X, ‘__slots__’, []):. skriv ut (attr, ‘= & gt;’, getattr (X, attr))

& Gt; & gt; & gt; dir (X) # dir () inkluderer alle spornavnene.

Nar slik generalitet er mulig, blir slots sannsynligvis best behandlet som klassegenskaper, i stedet for a forsoke a forme dem til a virke som de samme forekomstegenskapene. For mer om slots generelt, se Python standard manuell sett. Se ogsa pa et eksempel som tillater attributter basert pa bade __slots__ og __dict__-lagring i Private Decorator-diskusjonen i kapittel 38.