Python和科学计算认证群组  - 讨论区

标题:tkinter如何使用lambda?

2011年08月23日 星期二 15:19

[code]

  1. from Tkinter import *
  2. fields = 'Name', 'Job', 'Pay'
  3.  
  4. def fetch(event,entries):
  5.    for entry in entries:
  6.        print 'Input => "%s"' % entry.get()       # get text
  7.        print  event.widget
  8.  
  9.  
  10. def makeform(root, fields):
  11.    entries = []
  12.    for field in fields:
  13.        row = Frame(root)                           # make a new row
  14.        lab = Label(row, width=5, text=field)       # add label, entry
  15.        ent = Entry(row)
  16.        row.pack(side=TOP, fill=X)                  # pack row on top
  17.        lab.pack(side=LEFT)
  18.        ent.pack(side=RIGHT, expand=YES, fill=X)    # grow horizontal
  19.        entries.append(ent)
  20.    return entries
  21.  
  22. if __name__ == '__main__':
  23.    root = Tk()
  24.    ents = makeform(root, fields)
  25.    root.bind('<Return>', lambda event,entries=ents: fetch(event,entries))      
  26.    Button(root, text='Fetch', command= lambda event:fetch(event,entries)).pack(side=LEFT)   
  27.    root.mainloop()

[/code]

上面的代码,bind方法绑定的enter事件可以使用,但是那个button上面的command命令不知道如何修改,才能使得这个程序正常运行,请问,如何修改第26句话?

2011年08月24日 星期三 09:23

Button的command参数是一个不带参数的函数,因此将其改为:

Button(root, text='Fetch', command= lambda :fetch(None,ents)).pack(side=LEFT)

这样一来,fetch()中的程序就不能正确输出event.widget了,因此判断一下:

if event:

    print event.widget

2011年08月27日 星期六 11:21

请看下面的四段代码:

code1  ok
from Tkinter import *
from functools import partial
fields = 'Name', 'Job', 'Pay'
   
def fetch(entries,event):
    for entry in entries:
       print 'Input => "%s"' % entry.get()       
    print  event
   
   
def makeform(root, fields):
    entries = []
    for field in fields:
        row = Frame(root)                         
        lab = Label(row, width=5, text=field)     
        ent = Entry(row)
        row.pack(side=TOP, fill=X)                 
        lab.pack(side=LEFT)
        ent.pack(side=RIGHT, expand=YES, fill=X)   
        entries.append(ent)
    return entries
         
   
if __name__ == '__main__':
         
    root = Tk()
    ents = makeform(root, fields)
    root.bind('<Return>', partial(fetch,ents))
    root.mainloop()

code2   fail  i don't understand  why  ?
from Tkinter import *
from functools import partial
fields = 'Name', 'Job', 'Pay'
   
def fetch(entries,event):
    for entry in entries:
       print 'Input => "%s"' % entry.get()       
    print  event
   
   
def makeform(root, fields):
    entries = []
    for field in fields:
        row = Frame(root)                         
        lab = Label(row, width=5, text=field)     
        ent = Entry(row)
        row.pack(side=TOP, fill=X)                 
        lab.pack(side=LEFT)
        ent.pack(side=RIGHT, expand=YES, fill=X)   
        entries.append(ent)
    return entries
         
   
if __name__ == '__main__':
         
    root = Tk()
    ents = makeform(root, fields)
    root.bind('<Return>', partial(fetch,entries=ents))
    root.mainloop()
   
code3:  fail  i know the reason
from Tkinter import *
from functools import partial
fields = 'Name', 'Job', 'Pay'
   
def fetch(event,entries):
    for entry in entries:
       print 'Input => "%s"' % entry.get()       
    print  event
   
   
def makeform(root, fields):
    entries = []
    for field in fields:
        row = Frame(root)                         
        lab = Label(row, width=5, text=field)     
        ent = Entry(row)
        row.pack(side=TOP, fill=X)                 
        lab.pack(side=LEFT)
        ent.pack(side=RIGHT, expand=YES, fill=X)   
        entries.append(ent)
    return entries
         
   
if __name__ == '__main__':
         
    root = Tk()
    ents = makeform(root, fields)
    root.bind('<Return>', partial(fetch,ents))
    root.mainloop()

code4:  ok
from Tkinter import *
from functools import partial
fields = 'Name', 'Job', 'Pay'
   
def fetch(event,entries):
    for entry in entries:
       print 'Input => "%s"' % entry.get()       
    print  event
   
   
def makeform(root, fields):
    entries = []
    for field in fields:
        row = Frame(root)                         
        lab = Label(row, width=5, text=field)     
        ent = Entry(row)
        row.pack(side=TOP, fill=X)                 
        lab.pack(side=LEFT)
        ent.pack(side=RIGHT, expand=YES, fill=X)   
        entries.append(ent)
    return entries
         
   
if __name__ == '__main__':
         
    root = Tk()
    ents = makeform(root, fields)
    root.bind('<Return>', partial(fetch,entries=ents))
    root.mainloop()
   
code1,code4运行正常,
code2 不能工作,我知道原因,

为何code3就不能工作呢?

2011年08月29日 星期一 07:12

code2:

root.bind('<Return>', partial(fetch,entries=ents))

而fetch()的参数为: fetch(entries,event)。因此调用partial产生的函数时,会给entries传递2个参数,出错。

code3:

看看出错的原因就知道是两个参数反了。

 

2011年08月29日 星期一 20:31

请你比较一下code1和code2,就只有一个地方不同,

code1是

root.bind('<Return>', partial(fetch,ents))

code2是

root.bind('<Return>', partial(fetch,entries=ents))

为何不能用entries=ents?

 

 

2011年08月30日 星期二 12:40

可以写一个小程序验证:

from functools import partial

 

 

def f(a,b):

    print a,b

 

g = partial(f, a=10)

h = partial(f, 10)

h(20)

g(20)

 

g(20)出错,至于为什么,请先仔细阅读partial的文档。

 

http://docs.python.org/library/functools.html#functools.partial

2011年08月30日 星期二 14:43

functools.partial(func[, *args][, **keywords])

Return a new partial object which when called will behave like func called with the positional arguments args and keyword arguments keywords. If more arguments are supplied to the call, they are appended to args. If additional keyword arguments are supplied, they extend and override keywords. Roughly equivalent to:

def partial(func, *args, **keywords):
    def newfunc(*fargs, **fkeywords):
        newkeywords = keywords.copy()
        newkeywords.update(fkeywords)
        return func(*(args + fargs), **newkeywords)
    newfunc.func = func
    newfunc.args = args
    newfunc.keywords = keywords
    return newfunc

The partial() is used for partial function application which “freezes” some portion of a function’s arguments and/or keywords resulting in a new object with a simplified signature. For example, partial() can be used to create a callable that behaves like the int() function where the base argument defaults to two:

>>> from functools import partial
>>> basetwo = partial(int, base=2)
>>> basetwo.__doc__ = 'Convert base 2 string to an int.'
>>> basetwo('10010')
18 

看了半天,没有明白??

2011年08月30日 星期二 15:19

你把文档中的那个partial的实现函数复制到你的测试程序前面调试一下,而不从functools载入:

def partial(func, *args, **keywords):

    def newfunc(*fargs, **fkeywords):
        newkeywords = keywords.copy()
        newkeywords.update(fkeywords)
        return func(*(args + fargs), **newkeywords)
    newfunc.func = func
    newfunc.args = args
    newfunc.keywords = keywords
    return newfunc

def f(a,b):

    print a,b

 

g = partial(f, a=10)

h = partial(f, 10)

h(20)

g(20)

 

实际上, g(20),相当于调用了f(20, a=10),如果你明白为什么f(20, a=10)会出错的话,就明白为什么你的程序出错了。

如下红色区域有误,请重新填写。

    你的回复:

    请 登录 后回复。还没有在Zeuux哲思注册吗?现在 注册 !

    Zeuux © 2024

    京ICP备05028076号