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