Chci se naučit pracovat s dekorátory – Python – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu
Reklama
Reklama

Chci se naučit pracovat s dekorátory – Python – Fórum – Programujte.comChci se naučit pracovat s dekorátory – Python – Fórum – Programujte.com

 

Toto vlákno bylo označeno za vyřešené.
Spuštěný nový filmový web Filmožrouti.cz — vše o Avengers, Pacific Rim, Thor, Star Wars…
Váchyč0
Duch
1. 7. 2018   #1
-
0
-

Následuje můj kód třídy zt (jako zkušební třída):
(pod kódem jsou má přání a dotazy)

class zt:

    """
    Trida zt slouzi jen jako obetni beranek pro psi kusy.
    """

    _data = 0

    def __init__(self):
        """
        vstup: neni
        vystup: None
        --
        Metoda __init__ inicializuje tridu zt. Mimo to nedela nic.
        """

        pass

    @property
    def _data(self):
        """
        Metoda data.getter vraci hodnotu promenne >_data< .
        """

        vystup = self._data
        return vystup

    @_data.setter
    def _data(self, nova_data):
        """
        Metoda data.setter uklada retezec >nova_data< do promenne >self._data<
        """
        assert type(nova_data) == int, "data.setter: neplatny vstup"

        self._data = nova_data

Asi jste našli něco, co je tam špatně. Protože to fakt nefunguje. Já se učím pracovat s dekorátory. Zhruba jsem pochopil, že dekorátor je fce, která si jako svůj argument bere jinou fci, kterou nějakým způsobem pozměňuje. Z mého pohledu fce property vrací nějakou proměnnou (tady jsou to _data) .

1. DOTAZ: Nevěřím, že property dělá jenom tohle. Určitě nabízí něco víc. Co vlastně dělá? V čem je tak dobrá?

Dočetl jsem se, že každý atribut má tři vlastnosti:
getter (tuhle vlastnost by měla zastupovat fce property.... je to tak?)
setter
deleter
U dekorátoru @_data.setter vidím už smysl v tom, že do něj můžu přidat nějaké omezení jako je ten můj assert. To už je něco navíc, to už se mi líbí, že vidím něco, čím to původní opravdu měním. No ale taky vidím, že to nefunguje. Zkoušel jsem tohle:

zt._data = "a"

a čekal jsem, že se vyvolá AssertionError, ale nevyvolal se.

2. DOTAZ: V čem dělám chyby?

Učím se z knihy Python 3 - Výukový kurz .... ty dekorátory mě žerou teda. Prosím poraďte mi.

Nahlásit jako SPAM
IP: 94.230.156.–
gna
~ Anonymní uživatel
726 příspěvků
1. 7. 2018   #2
-
+1
-
Zajímavé

Property je prostě "vlastnost" objektu. Jako proměnná. Jde ji číst, měnit a smazat (pokud jsou dané operace definované) 

obj.property

Dekorátor @property z metody vytvoří stejnojmennou property a ta metoda bude fungovat jako její getter. To je celé. Pointa je v podstatě jen v tom jak se to jeví "zvenku".

Chybu máš už v tom getteru. Vracíš _data, cože je přeci property s getterem, který se tak znova zavolá a zacyklí se to.

A pak v tom testovacím přiřazení nepracuješ s objektem (takže se nezavolá setter property), ale s třídou (takže se přesmahne definice property).

class ZT:
    _data = 0

    @property
    def data(self):
        return self._data

    @data.setter
    def data(self, nova_data):
        assert type(nova_data) == int, "data.setter: neplatny vstup"
        self._data = nova_data


zt = ZT()
zt.data = "a"
Nahlásit jako SPAM
IP: 213.211.51.–
Kit+14
Guru
2. 7. 2018   #3
-
+1
-
Zajímavé

#1 Váchyč
Dekorátory v Pythonu fungují trochu jinak než třeba v C#. Tvoří obálku, ve které se například validují vstupní data nebo formátují výstupní data. Holé gettery a settery, jak je známe třeba z Javy, by byly zbytečné, protože se můžeš odkázat na atributy přímo. Jenže obvykle chceme nějaké zapouzdření, proto místo těchto přístupových metod raději potřebnou funkcionalitu vložíme dovnitř třídy, což tvůj příklad nedělá.

Příklad, který jsi napsal, by se při zachování stejné funkčnosti dal zkrátit takhle: 

zt = lambda: None
zt.data = 42
print(zt.data)
Nahlásit jako SPAM
IP: 2a00:1028:83a0:37a6:9d86:...–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
Váchyč0
Duch
2. 7. 2018   #4
-
0
-

#2 gna
Ono se mi to právě někdy cyklilo a to jsem taky chtěl vědět, proč. Tak to vím. Díky. Teď už je mi to jasnější :)

Nahlásit jako SPAM
IP: 94.230.156.–
Váchyč0
Duch
2. 7. 2018   #5
-
0
-

V tomto komentáři odpovím vám oběma. Děkuji vám za rady, pomohly mi.

Jednak jsem zjistil, proč se mi to cyklilo a taky.... vůbec jsem nepracoval s instancí té třídy, já jsem chtěl pro to přiřazení použít tu třídu jako takovou. To mi psal gna . Dekorátory se mi začínají líbit, představuju si je jako takové chránící zapouzdřovací fce. To se mi líbí. A už mi ten kód funguje, tak dík lidi.

Nahlásit jako SPAM
IP: 94.230.156.–
Kit+14
Guru
2. 7. 2018   #6
-
0
-

#5 Váchyč
Zkus si do příkladu od @gna přidat ještě takový dekorátor: 

    @property
    def celkem(self):
        return "Celkem: {} Kč".format(self._data)

print(zt.celkem)
Nahlásit jako SPAM
IP: 2a00:1028:83a0:37a6:9d86:...–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
Váchyč0
Duch
2. 7. 2018   #7
-
0
-

#6 Kit
Jo jo. Tím mi chceš ukázat smysl toho property žejo? Píše mi to "Celkem: 0 Kč" (to jsem ale boháč!)

Chápu, to beru :)

Nahlásit jako SPAM
IP: 94.230.156.–
Kit+14
Guru
2. 7. 2018   #8
-
0
-

#7 Váchyč
Ano, chtěl jsem tím ukázat smysl dekorátorů. Na vstupu ošetření vstupu a na výstupu jeho formátování či jiná prezentace. Můžeš si zkusit další, např. predikáty (isEmpty, hasName, ...) nebo modifikátory (add). Místo tohoto modifikátoru však bývá výhodnější přetížení operátoru "+=", který se dá využít např. i pro přidávání položky do kolekce. 

account = Account(100, "Počáteční stav")
account += (42, "Příjem")
account -= (222, "Výdaj")   # Tady to klidně může vyhodit výjimku
Nahlásit jako SPAM
IP: 194.228.68.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 22 hostů

Podobná vlákna

Program prestal pracovať? — založil Kent

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032018 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý