IT rekvalifikácia. Seniorní programátori zarábajú až 6 000 €/mesiac a rekvalifikácia je prvým krokom. Zisti, ako na to!

Diskusia – 3. diel - Hracia kocka v Pythone - Zapuzdrenie a konštruktor

Späť

Upozorňujeme, že diskusie pod našimi online kurzami sú nemoderované a primárne slúžia na získavanie spätnej väzby pre budúce vylepšenie kurzov. Pre študentov našich rekvalifikačných kurzov ponúkame možnosť priameho kontaktu s lektormi a študijným referentom pre osobné konzultácie a podporu v rámci ich štúdia. Toto je exkluzívna služba, ktorá zaisťuje kvalitnú a cielenú pomoc v prípade akýchkoľvek otázok alebo projektov.

Komentáre
Avatar
Benjibs
Člen
Avatar
Benjibs:8.6.2014 21:33

Aj metóda __new__ sa oplatí podľa mňa často využívať, nie len __init__.
Napríklad keď validujeme argumenty dané do "konštruktora", je zbytočné vytvárať objekt v prípade nesplnenia podmienok.

Odpovedať
8.6.2014 21:33
1 + 1 = 2
Avatar
hanpari
Člen
Avatar
Odpovedá na Benjibs
hanpari:10.6.2014 5:51

Ahoj,
můžeš napsat příklad? Já v jakési chytré knížce našel, že metodu __new__() je lepší nepoužívat, pokud nemáš vyslovený důvod.

Tady jsem našel hezké vysvětlení, když jsem hledal, ale to podle mne moc neodpovídá tomu, co píšeš ty. Ale třeba se pletu.

*
Use __new__ when you need to control the creation of a new instance. Use __init__ when you need to control initialization of a new instance.

__new__ is the first step of instance creation. It's called first, and is responsible for returning a new instance of your class. In contrast, __init__ doesn't return anything; it's only responsible for initializing the instance after it's been created.

In general, you shouldn't need to override __new__ unless you're subclassing an immutable type like str, int, unicode or tuple.*

http://stackoverflow.com/…new-and-init

 
Odpovedať
10.6.2014 5:51
Avatar
Benjibs
Člen
Avatar
Odpovedá na hanpari
Benjibs:10.6.2014 6:22

Ahoj,


Use __new__ when you need to control the creation of a new instance. Use __init__ when you need to control initialization of a new instance.**
Presne tak, ja "kontrolujem" vytváranie novej instancie, a to tak, že v prípade nesplnenia vstupných podmienok ju vôbec nevytvorím :)

#...
def __new__(cls, arg1, arg2):
   if arg1.skaredy():
       raise UglyArgException('Pfffff.')
       #...

Musíš uznať, že je zbytočné vytvárať objekt, (čiže vstúpiť do __init__), ak takto získaný objekt bude vďaka zlým argumentom v porušenom stave.

Editované 10.6.2014 6:23
Odpovedať
10.6.2014 6:22
1 + 1 = 2
Avatar
hanpari
Člen
Avatar
Odpovedá na Benjibs
hanpari:10.6.2014 7:17

Díky, chápu, špatně jsem si přečetl ten popis. Pochopil jsem to přesně obráceně. Takhle to dává smysl :)

 
Odpovedať
10.6.2014 7:17
Avatar
hanpari
Člen
Avatar
Odpovedá na Benjibs
hanpari:10.6.2014 16:53

Tak beru zpět. Není mi to jasné o nic víc než předtím. Z toho, co jsem vyzkoušel a následně přečetl, je můj osobní dojem takový, že do __new__ se pouštět nemá smysl. Viz můj nefunkční kód:

class Test():
        def __new__(self):
                print("new")
        def __init__(self):
                print("init")
>>>new

Tohle mne trochu překvapilo, a když jsem šel po tom hlouběji, našel jsem tuhle větu:

__new__() is intended mainly to allow subclasses of immutable types (like int, str, or tuple) to customize instance creation.

Což tak trochu odporuje tomu, jak __new__ nejspíš používáš ty. Což samozřejmě nutně nemusí znamenat, že ho používáš špatně. V každém případě bych byl rád, kdybys sem mohl hodit kompletní příklad :)

 
Odpovedať
10.6.2014 16:53
Avatar
Benjibs
Člen
Avatar
Odpovedá na hanpari
Benjibs:10.6.2014 17:49

Tebou uvedený kód nefunguje preto,
lebo vždy na konci metódy __new__ je potrebné dať (čo si ty neurobil):

return super(NAZOV_TRIEDY, cls).__new__(cls)

Až toto, čiže zavolanie metódy __new__ u rodičovskej triedy vytvorí tú instanciu.
Takže všetko by malo fungovať správne.

class Test(object):
        def __new__(cls):
                print("new")
                return super(Test, cls).__new__(cls)

        def __init__(self):
                print("init")
 >>>new
    init
Editované 10.6.2014 17:50
Odpovedať
10.6.2014 17:49
1 + 1 = 2
Avatar
hanpari
Člen
Avatar
Odpovedá na Benjibs
hanpari:10.6.2014 17:58

Díky, já se pak později dočetl, že to fungovat nemůže, jenom mi není jasné, co se vlastně děje, například co se schovává pod tím parametrem cls? Už jsem pochopil, že __new__ je sdílená funkce a syntaxe super je mi také jasná. Ale když na to hledím, přijde mi, že je to uzavřená smyčka, kde si předávám totéž cls pořád do kola :)
Nevím, jestli jsem se vyjádřil dost jasně, ale jde mi o úplně první volání funkce __new__. Jaký dostává parametr?

Editované 10.6.2014 18:01
 
Odpovedať
10.6.2014 17:58
Avatar
Benjibs
Člen
Avatar
Odpovedá na hanpari
Benjibs:10.6.2014 18:32

"cls" = "class", tým argumentom je samotná trieda, v tomto prípade "Test".
Nekončený cyklus to nie je. Ono to len prebuble cez metódy __new__ celej hierarchie tried a zastaví sa to u triedy "object".

Odpovedať
10.6.2014 18:32
1 + 1 = 2
Avatar
hanpari
Člen
Avatar
Odpovedá na Benjibs
hanpari:10.6.2014 21:07

Díky moc. Nebudu tvrdit, že zcela chápu, proč to tak je, ale aspoň už vím, jak to případně vyluštit.

 
Odpovedať
10.6.2014 21:07
Avatar
Jiko
Člen
Avatar
Jiko:3.2.2015 9:15

Ahoj,

Jsem programátor nováček. Mohl by mi někdo prosím vysvětlit jak přesně funguje sestistenna.hod()?

Metoda hod() generuje náhodná čísla od 1 do počtu stěn kostky. Pokud to dobře chápu tak metoda říká, co má instance dělat. Ale hod() neříká co má dělat, pouze generuje čísla. Takže výsledek je třeba něco jako sestistenna.4. Chápu to dobře?

 
Odpovedať
3.2.2015 9:15
Robíme čo je v našich silách, aby bola tunajšia diskusia čo najkvalitnejšia. Preto do nej tiež môžu prispievať len registrovaní členovia. Pre zapojenie sa do diskusie sa zaloguj. Ak ešte nemáš účet, zaregistruj sa, je to zadarmo.

Zatiaľ nikto nevložil komentár - buď prvý!