[python] (no subject)

Jakub Vojáček Jakohv na seznam.cz
Sobota Říjen 28 17:39:52 CEST 2006


Dík, už mi to funguje;)

> ------------ Původní zpráva ------------
> Od: Radek Kanovsky <rk na dat.cz>
> Předmět: Re: [python] (no subject)
> Datum: 28.10.2006 13:47:24
> ----------------------------------------
> On Sat, Oct 28, 2006 at 10:10:39AM +0200, Jakub Vojáček wrote:
> 
> > mám problém tady stím:
> > 
> > from Tkinter import*
> > def pis(co):
> >     print co
> > okno=Tk()
> > menubar = Menu(okno)
> > menu = Menu(menubar, tearoff=0)
> > cisla=[1,2,3,4,5,6,7,8,9,10]
> > for prvek in cisla:      
> >     menu.add_cascade(label=prvek,command=lambda: pis(prvek))
> > menubar.add_cascade(label="cisla",menu=menu)    
> > okno.config(menu=menubar)
> > mainloop()
> > 
> > když v tom menu kliknu na jakoukoliv položku tak se vždy napíše
> > 10? proč?mělo by to přece napsat to číslo na který klikám
> 
> Prolem je v definici lambda funkce. Promenna 'prvek' je v te funkci jako
> volna promenna a zkompilovana lambda vypada nejak takto:
> 
>     lambda: pis(LOAD_DEREF('prvek'))
> 
>     Nebo lambda: pis(LOAD_GLOBAL('prvek')), pokud je definovana na
>     globalni urovni.
> 
> Ale ne takto:
> 
>     lambda: pis(1)
>     lambda: pis(2)
>     ....
> 
> Cili ve vasem pripade v tom cyklu v podstate vznikne 10 shodnych
> funkci, ktere si hodnotu prvku zjistuji az za behu a ta je
> po skonceni cyklu rovna hodnote 10. Vice o tom najdete pres
> klicova slova "python closures".
> 
> Aby to fungovalo, musi se pouzit nejaky trik:
> 
>     lambda p=prvek: pis(p)
> 
> nebo
> 
>     new.instancemethod(lambda p:pis(p), prvek, type(prvek))
> 
> Tim se vygenerovana instance lambda funkce vzdy svaze s konkretnim prvkem.
> Prvni varianta je jednodussi, ale meni signaturu funkce, coz muze nekdy
> vadit. Druha verze vytvori fiktivni anonymni metodu konkretniho objektu
> prvek (bound method), ikdyz trida int zadnou takovou metodu nema.
> Je to vlastne zkracena verze varianty s pomocnou tridou:
> 
>     class PisInt:
>         def __init__(self, prvek):
>             self.p = prvek
>         def __call__(self):
>             return pis(self.p)
> 
>     for prvek in cisla:      
>         menu.add_cascade(label=prvek,command=PisInt(prvek))
> 
> 
> Radek Kaňovský
> _______________________________________________
> Python mailing list
> Python na py.cz
> http://www.py.cz/mailman/listinfo/python
> 
> 
> 

Blujacker


Další informace o konferenci Python