Get/Set a Property
Dotaz
Celkem mě zaujala ta debata kolem getters and setters. Osobně jsem zastánce používáni téhle metody. Čistě protože si myslím, ze o nastavovaní/vracení atributu by se mela starat třída. Četl jsem ten text tady: http://dirtsimple.org/2004/12/python-is-not-java.html
A zaujala me věta: In Python, this is silly, because you can start with a normal attribute and change your mind at any time, without affecting any clients of thé class.
Asi je to jen mou neznalosti, ale přeci když budu důsledně používat get a set metody, tak si při případné změně atributu ulehčím práci, jelikož taková změna bude znamenat editaci pouze samotné třídy a nebudu muset procházet cely kód a hledat kde všude se na třídu odvolávám.
Příklad
class Opicka: def __init__(self): self.nick = "" def setNick(self, nick): self.nick = nick def getNick(self): return self.nick orangutan = Opicka() orangutan.setNick("Tonda") print orangutan.getNick()
Odpověď
No to zrovna u jazyků, které mají property je zbytečnost, ne? Vždycky jsem považoval gettery/settery za nouzové východisko u jazyků, které nemají v syntaxi jazyka property - jako třeba Java, nebo C++.
Pokud používáš get/set metody explicitně, tak děláš práci úplné zbytečnou. Jednoduchý příklad:
# Třída class C(object): def __init__(self): self.x = 0 def magic(self): self.x = self.x * 10 # Program pom = C() pom.x = 11 print pom.x pom.magic() print pom.x
Vše je OK, ale z nějakého obskurního důvodu je najednou do x místo nuly potřeba ukládat dvojnásobek kladných přiřazovaných hodnot, místo záporného čísla nulu.
Není nic jednoduššího, než změnit atribut x na property x. Property v Pythonu funguje tak, ze u vytvořené property nadefinuješ, jaká funkce se vola při přístupu k property pro čtení (getter) a při přístupu k property pro zápis (setter):
class C(object): def __init__(self): self._x = 0; def magic(self): self.x = self.x * 10 def get_x(self): return(self._x) def set_x(self, value): if value >= 0: self._x = value * 2 else: self._x = 0 x = property(get_x, set_x) # Nyní mohu bez problému provést původní program: pom = C() pom.x = 11 print pom.x pom.magic() print pom.x
a mám i požadované chovaní. Všimni si, ze požadovaná změna chovaní se projevila i ve funkci C.magic() která k property x taktéž přistupuje. Pokud by ses tomuto chtěl vyhnout, tak stačí změnit self.x na self._x
Čili tím, ze explicitně voláš get_x a set_x tak sice neděláš chybu, ale děláš zbytečnou práci a navíc to vypadá děsně.
Záložky, oblíbené
- překlad slova property: http://slovnik.seznam.cz/?q=property&lang=en_cz
- http://dirtsimple.org/2004/12/python-is-not-java.html