[python] Deferred output

matesfila matesfila na host.sk
Čtvrtek Únor 11 14:47:31 CET 2010


Ďakujem za reakcie, obidve veľmi pomohli a je mi to oveľa jasnejšie!
A vyjadrujem obdiv, jak vám to myslí ešte aj o štvrtej ráno :-)

Uvedomil som si pri tomto probléme jednu zaujímavú vlastnosť jazyka
Python, ktorá súvisí s tým deferred output. Python vlastne umožňuje
definovať funkcie, ktoré pracujú s premennými, ktoré ešte neexistujú. To
bol pre mňa dosť zarážajúci objav :-)

Triviálny prípad by bol asi takýto:

""" zdrojový kód """
def f():
    print(x)

x = 9
f()
""" koniec zdrojového kódu """

Funkcia f, ktorá využíva premennú x, môže byť definovaná ešte predtým, ako
sa definuje samotné x. Kontrola existencie x sa vykonáva až pri samotnom
volaní funkcie f. Pri jej volaní sa zrejme najprv skontroluje, či x
existuje v lokálnom priestore funkcie, a ak neexistuje, skontroluje sa
globálny priestor. Podstatné ale je, že tá kontrola sa robí až pri volaní
funkcie, ak som tomu teda správne pochopil.

Pre aké jazyky je vlastné takéto chovanie typické? Súvisí to s
beztypovosťou jazyka, alebo s tým, že je jazyk skriptovací, alebo s čím
vlastne?

Tento "deferred" jav ma na začiatku dosť miatol, pretože som robil v Jave
a tam takéto niečo rozhodne nebolo možné. No ale v príklade tej fibonacci
funkcie je to dotiahnuté asi na úplné maximum, keďže sa tam s premennou
output pracuje akosi rekurzívne... uff :-)

Ešte raz vďaka!

Matúš

On Thu, 11 Feb 2010 04:07:22 +0100 (CET), Jan Fuchs
<fuky na sunstel.asu.cas.cz> wrote:
> Zdravím,
> ještě doplním Petrův mail. Myslím, že pro pochopení je šikovné spustit
si
> ipython, nejasné části kódu vyzkoušet a poté se to snažit pochopit jako
> celek.
> 
>      from itertools import islice, tee, chain
> 
>      def fibonacci():
>          # vraci generator object
>          # napr. pro output = [0, 1, 2] bude generator obsahovat polozky
0
>          az 2
>          def deferred_output():
>              for i in output:
>                  yield i
> 
>          # fce tee() prijima jako prvni argument iterable object a
>          # jako druhy argument pocet nezavislych iteratoru, ktere vrati
>          jako tuple
>          # tj. result, c1, c2 maji stejny obsah tj. to co vraci
>          deferred_output()
>          result, c1, c2 = tee(deferred_output(), 3)
> 
>          # fce map() spusti fci add(), ktere postupne predava jako prvni
>          argument
>          # polozky z prvniho iteratoru a jako druhy argument polozky z
>          druheho
>          # iteratoru, vraci pole s vysledky fce map()
>          #
>          # fce islice() prijme iterator c2 a vrati iterator, ktery
>          obsahuje jeho
>          # polozky od 1 do konce
>          paired = map(add, c1, islice(c2, 1, None))
> 
>          # fce chain() spoji predane iteratory a vrati je jako jeden
>          output = chain([0, 1], paired)
>          return result
> 
>      print(list(islice(fibonacci(), 50)))
> 
>           S pozdravem Jan Fuchs
> 
> --
> /**************************************************************
> *   _    Žádný program není bezchybný, dokonalý ani nejlepší, *
> *  °v°   to samé platí i o lidech a nejen o nich.             *
> * /(_)\                                      -- Jan Fuchs --  *
> *  ^ ^                                                        *
> *        http://www.fuky.org   Jabber: jan.fuchs.cz na gmail.com *
> **************************************************************/


Další informace o konferenci Python