Python-slotsegenskaper

Fa via App Store Les dette innlegget i var app!

Klasseegenskaper og __setattr__.

I Python-klassen, nar jeg bruker __setattr__, har det forrang over egenskaper definert i denne klassen (eller noen grunnklasser). Vurder folgende kode:

Nar jeg lager klassen og prover a sette x, kalles __setattr__ i stedet for set_x:

Det jeg vil oppna er at den faktiske koden i __setattr__ ble kalt bare hvis det ikke er noen relevant egenskap, dvs. test.x = 2 skal ringe set_x. Jeg vet at jeg kan oppna dette enkelt ved a manuelt sjekke om a er «x» __setattr__, men dette ville gjore en darlig design. Er det en smartere mate a sikre riktig oppforsel i __setattr__ for hver eiendom som er definert i klassen og alle baseklassene?

Sokeordren som Python bruker for attributter, gar slik:

__getattribute__ og __setattr__ Datadeskriptorer, som eiendom Instansvariabler fra objektets __dict__ (nar du setter inn et attributt, slutter soket her) Ikke-Data-beskrivere (som metoder) og andre klassevariabler __getattr__.

Siden __setattr__ er forst pa linje, hvis du har en, ma du gjore det smart, med mindre at det skal handtere all attributtinnstilling for klassen din. Det kan v re smart pa to mater: Gjor det bare til a handtere et spesifikt sett attributter, eller fa det til a handtere alt, men noen sett med attributter. For de du ikke vil at den skal handtere, ring super () .__ setattr__.

For eksempelklassen din er det sannsynligvis enklest a handtere «alle attributter unntatt» x «»:

Dette er ikke en kollisikker losning, men som du foreslo, kan du sjekke om en eiendom blir satt opp ved a prove a fa tilgang til eiendomsobjektet, fra klassens attributter (ved hjelp av getattr pa klassen objektet).

EDIT: erstattet selv .__ dict __ [a] = v med super (Test, self) .__ setattr __ (a, v), som sett pa @ Blckknghts svar.

AFAIK, Det er ingen ren mate a gjore dette pa. Problemet her oppstar fra asymmetrien mellom __getattr__ og __setattr__. Den forstnevnte kalles bare hvis attributtet ved de normale midler mislykkes, men sistnevnte kalles ubetinget. Siden det ikke er en generell mate at __setattr__ vil mislykkes, vet jeg ikke om det er en mate at denne oppforselen kan endres.

Til slutt tror jeg den eneste maten a fa den oppforelsen du vil ha, er a kaste egenskapene til dine egenskaper i __setattr__-funksjonen. Og hvis du gjor det, kan du like godt brette oppgangene til getters i __getattr__ til ha alt vedlikeholdsbart fra 1 sted.

Jeg opplevde disse problemene flere ganger, min foretrukne losning er folgende:

For hver eiendom [eiendom] definerer du Get_ [Property] og Set_ [Property] -funksjonene som du gjor, men uten a bruke dekoratorer Endre __getattr__ og __setattr__ slik at de sjekker for n rv r av disse funksjonene og bruker dem hvis de er tilgjengelige.

Her er et minimalt eksempel:

Fordelen med denne metoden er at den opprettholder normal oppforsel for alle attributter, bortsett fra de som har «getter» og «setter» -metoder, og at den ikke krever noen modifikasjoner av funksjonene __getattr__ og __setattr__ nar du legger til eller fjerner egenskaper.


Hilsen! Vil du spille i det beste kasinoet? Vi forbereder det for deg. Spill her nå!