我正在使用lambda函数进行tkinter的GUI编程.

最近我在实现打开文件的按钮时遇到困难:

self.file=""

button = Button(conf_f, text="Tools opt.",

command=lambda: tktb.helpers.openfile(self.file))

如您所见,我想定义一个可以更新的文件路径,并且在创建GUI时不知道.

我遇到的问题是我之前的代码是:

button = Button(conf_f, text="Tools opt.",

command=lambda f=self.file: tktb.helpers.openfile(f))

lambda函数有一个关键字参数来传递文件路径.在这种情况下,当self.file为时,参数f未更新.

我从代码片段中获取了关键字参数,并且我在任何地方都使用它.显然我不应该……

这对我来说仍然不清楚……有人可以解释一下这两种lambda形式之间的区别以及何时使用另一种形式?

谢谢!

解决方法:

我会尝试更深入地解释它.

如果你这样做

i = 0

f = lambda: i

你创建一个函数(lambda本质上是一个函数),它访问它的封闭范围的i变量.

在内部,它通过一个包含i的所谓闭包来实现.松散地说,它是一种指向真实变量的指针,它可以在不同的时间点保持不同的值.

def a():

# first, yield a function to access i

yield lambda: i

# now, set i to different values successively

for i in range(100): yield

g = a() # create generator

f = next(g) # get the function

f() # -> error as i is not set yet

next(g)

f() # -> 0

next(g)

f() # -> 1

# and so on

f.func_closure # -> an object stemming from the local scope of a()

f.func_closure[0].cell_contents # -> the current value of this variable

在这里,i的所有值 – 在它们的时间 – 存储在所述闭包中.如果函数f()需要它们.它从那里得到它们.

您可以在反汇编列表中看到差异:

这些函数a()和f()反汇编如下:

>>> dis.dis(a)

2 0 LOAD_CLOSURE 0 (i)

3 BUILD_TUPLE 1

6 LOAD_CONST 1 ( at 0xb72ea650, file "", line 2>)

9 MAKE_CLOSURE 0

12 YIELD_VALUE

13 POP_TOP

3 14 SETUP_LOOP 25 (to 42)

17 LOAD_GLOBAL 0 (range)

20 LOAD_CONST 2 (100)

23 CALL_FUNCTION 1

26 GET_ITER

>> 27 FOR_ITER 11 (to 41)

30 STORE_DEREF 0 (i)

33 LOAD_CONST 0 (None)

36 YIELD_VALUE

37 POP_TOP

38 JUMP_ABSOLUTE 27

>> 41 POP_BLOCK

>> 42 LOAD_CONST 0 (None)

45 RETURN_VALUE

>>> dis.dis(f)

2 0 LOAD_DEREF 0 (i)

3 RETURN_VALUE

将其与看起来像的函数b()进行比较

>>> def b():

... for i in range(100): yield

>>> dis.dis(b)

2 0 SETUP_LOOP 25 (to 28)

3 LOAD_GLOBAL 0 (range)

6 LOAD_CONST 1 (100)

9 CALL_FUNCTION 1

12 GET_ITER

>> 13 FOR_ITER 11 (to 27)

16 STORE_FAST 0 (i)

19 LOAD_CONST 0 (None)

22 YIELD_VALUE

23 POP_TOP

24 JUMP_ABSOLUTE 13

>> 27 POP_BLOCK

>> 28 LOAD_CONST 0 (None)

31 RETURN_VALUE

循环的主要区别是

>> 13 FOR_ITER 11 (to 27)

16 STORE_FAST 0 (i)

在b()与

>> 27 FOR_ITER 11 (to 41)

30 STORE_DEREF 0 (i)

在a()中:STORE_DEREF存储在单元格对象(闭包)中,而STORE_FAST使用“正常”变量,该变量(可能)的工作速度稍快一些.

lambda也有所不同:

>>> dis.dis(lambda: i)

1 0 LOAD_GLOBAL 0 (i)

3 RETURN_VALUE

这里有一个LOAD_GLOBAL,而上面的一个使用LOAD_DEREF.后者也是关闭的.

我完全忘记了lambda i = i:i.

如果您将值作为默认参数,它将通过完全不同的路径进入函数:i的当前值通过默认参数传递给刚刚创建的函数:

>>> i = 42

>>> f = lambda i=i: i

>>> dis.dis(f)

1 0 LOAD_FAST 0 (i)

3 RETURN_VALUE

这样函数被调用为f().它检测到缺少参数并使用默认值填充相应参数.所有这些都在调用函数之前发生;在函数中,您只需看到值并获取并返回.

还有另一种方法可以完成你的任务:只需使用lambda就好像它需要一个值:lambda i:i.如果你打电话给它,它会抱怨缺少一个参数.

但是你可以使用functools.partial来解决这个问题:

ff = [functools.partial(lambda i: i, x) for x in range(100)]

ff[12]()

ff[54]()

这个包装器获得一个可调用的和一些要传递的参数.生成的对象是一个可调用对象,它使用这些参数以及您为其提供的任何参数调用原始可调用对象.它可以在这里用来保持锁定到预期的值.

标签:python,lambda,tkinter

来源: https://codeday.me/bug/20190612/1228500.html

python一个函数可以有参数也可以没有参数_Python:有和没有关键字参数的lambda函数行为?...相关推荐

  1. pythonnamedtuple定义类型_python - namedtuple和可选关键字参数的默认值

    python - namedtuple和可选关键字参数的默认值 我正在尝试将一个冗长的空洞"数据"类转换为一个命名元组. 我的班级目前看起来像这样: class Node(obje ...

  2. python 高阶函数 与关键字参数

    修饰器 之前我一直有一个疑惑,就是修饰器里面对函数的操作为什么不能直接写进函数里面就好了吗?何必这么麻烦呢,当我进一步理解之后,原来修饰器的作用就是完成那些不能写进函数里面的功能的,好比必须要等到函数 ...

  3. PYTHON 笔记:函数的参数(关键字参数,默认参数,可变长参数,可变长的关键字参数)

    一般的函数参数是位置参数,位置不对会出问题 1.关键字参数 使用参数名提供的参数就是关键字参数,有了关键字参数,顺序就不会有影响. >>>def printGrade(name,ID ...

  4. python函数参数之必选参数,默认参数,可变参数,关键字参数

    Python的函数定义非常简单,但灵活度却非常大.除了正常定义的必选参数外,还可以使用默认参数.可变参数和关键字参数, 1 默认参数 定义形式:def calc(para1,para2=None):其 ...

  5. Python函数 — 位置参数和关键字参数

    1.参数分类 Python函数的参数可以分为默认参数,位置参数,关键字参数,可变参数.函数可以没有参数,也可以有多个参数. 形参:定义函数时的参数,如定义函数def func(a,b)的参数a,b是形 ...

  6. python函数用法详解2(变量的作用域(全局变量、局部变量)、共享全局变量、函数返回值、函数的参数(位置参数、关键字参数、默认参数、不定长参数)、拆包、交换变量值、引用、可变和不可变类型)

    1. 变量作⽤域         变量作⽤域指的是变量⽣效的范围,主要分为两类:局部变量和全局变量. 局部变量         定义在函数体内部的变量,即只在函数体内部⽣效. def testA(): ...

  7. Python自定义函数的位置参数和关键字参数

    1 位置参数和关键字参数 在<Python中自定义函数的方法>中提到,在调用函数时,可以根据函数参数的位置确定该参数的值,此时的参数叫做函数的位置参数,如图1所示. 图1 位置参数 从图1 ...

  8. python可变参数和关键字参数位置_python的位置参数、默认参数、关键字参数、可变参数区别...

    一.位置参数 调用函数时根据函数定义的参数位置来传递参数. #!/usr/bin/env python # coding=utf-8def print_hello(name, sex): sex_di ...

  9. Python Lambda函数的几种使用方法

    在进行编程时,一般我们会给一个函数或者变量起一个名字,该名称是用于引用或寻址函数变量.但是有一个低调的函数,你不需要赋予它名字,因此该函数也叫匿名函数.该函数就是Python中的Lambda函数,下面 ...

  10. python中关键字参数的特点_Python中的*可变参数与**关键字参数

    1.定义了一个需要两个参数的函数 def print_str(first, second): print first print second if __name__ == "__main_ ...

最新文章

  1. CSDN博客图片居中问题解决方案
  2. 飞桨领航团邀你出战!黑客松线下48H Coding Party等你来
  3. 微型计算机,单片机和单板机是,9、微型计算机、单片机和单板机是()
  4. QObject 的拷贝构造和赋值操作
  5. 数据结构与算法之转圈打印矩阵和旋转正方形矩阵
  6. 傅立叶变换学习(一)初步认识傅立叶变换
  7. Git的纯命令操作,Install,Clone , Commit,Push,Pull,版本回退,撤销更新,分支的创建/切换/更新/提交/合并,代码冲突...
  8. 2-5-666:放苹果
  9. MyBatis之输入(parameterType)与输出(resultType、resultMap)映射
  10. JS学习笔记2-JavaScript 语法
  11. 条款12:复制对象时勿忘其每一个部分
  12. 扩展JS格式化(Format)功能及评论树
  13. Eclipse中Java编程时快速生成set和get方法
  14. 接口测试工具-Jmeter使用笔记(六:从文本读取参数)
  15. 超强数据恢复软件【含注册码】
  16. 服务器部署Java项目详述
  17. 问学计算机的同学买什么电脑,学生用的笔记本电脑什么样的好
  18. 障碍物参考线交通规则融合器:Frame类
  19. 用友U9产品SOA设计架构遭技术质疑
  20. tortoise-orm连接多个数据库

热门文章

  1. fonts.googleapis.com不能访问时的解决方法
  2. UISlider 设置增量
  3. 《Windows程序设计》第三章学习心得(1)|图解消息机制
  4. 服务器端可控情形的Javascript跨域访问解决方法
  5. python爬取内容为空怎么剔除_用scrapy爬取网站内容时,如何忽略某些内容为空的值;...
  6. html日历框架,日历.html
  7. 基于机器视觉的安利纽崔莱瓶子外观检测
  8. C语言以字符形式读写文件
  9. 机器视觉:偏振镜光学原理和在机器视觉中的应用
  10. Python实用技法第26篇:定义实现最短匹配的正则表达式