Edit detail for GetSetProperty revision 2 of 1

2
Editor: geon
Time: 2009/02/11 17:02:49 GMT+1
Note: uprava

changed:
-
=======================
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

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ě.