python:工厂函数应该全部设置默认参数
来源:互联网 发布:怎样在mac上保存图片 编辑:程序博客网 时间:2024/06/05 19:46
python 中的工厂函数,简单理解就是:高阶函数的一种,可以返回函数的函数。
一般我们可以写出这样的工厂函数:
def func(x): return lambda: x
然后验证一下:
print(func(2)())# 2
输出为2。没错,就是我们期待的结果。
然后,再来一个带循环体的(错误的示范!):
def multi(x): ret = [] for ele in range(x): ret.append(lambda: ele) return ret
- 输出验证一下:
for action in multi(5): print(action(),end="\t")# 4 4 4 4 4
这时候就出问题了。lambda 并没有记住我们所期待的
ele
而是记住了最后一个ele
.
- 如何解决?
- 全部设置默认参数就好了。
那么修改后的代码如下(正确的示范):
def multi(x): ret = [] for ele in range(x): ret.append(lambda k=ele: k) return ret
- 输出如下
for action in multi(5): print(action(), end="\t")# 0 1 2 3 4
对于之前的func()
函数呢?当然也可以设置默认参数:
def func(x): return lambda p=x: p
通过对默认参数的设置,代码就不会依赖运行时的检查,而是在定义时就明确知道状态信息。
- 分析:为何定义了默认参数值,就可以避免循环中出现的问题?
以multi(x)
函数为例:其等价形式为:
def multi(x): ret = [] for ele in range(x): def temp(t=ele): return t ret.append(temp) return ret
- 在
def multi(x):
中,变量ele
和函数temp()
是同时被创建的。都是在multi(x)
函数被调用时创建。 - 而
def temp():
中的返回值t
是在temp()
函数被调用的时候创建。 - 而且这两个函数总是不能同时被调用。总是需要
multi(x)()
这样的方式去调用。也就导致了t
总是在ele
创建之后被创建。 - 所以在这样的场景下,如果不设置默认值,
t
返回的总是最后一个ele
的值。 - 而,如果给
temp()
函数设置了默认参数temp(t=ele)
,就强制在temp()
函数被创建的时候,就创建变量t
.这样刚好就达到了预期:在遍历的过程中,不断地去改变ele
的值,同时t
也随着ele
的改变而改变。(如果不做这种默认参数的设置。对t
的赋值实际上只发生了一次,也就是在temp()
被调用的时候发生了一次。)
总结:
x,ret,ele
都是在multi(x)
被调用的时候创建的temp()
的返回值,是在temp()
被调用的时候创建的temp()
总是在multi(x)
被调用之后才调用- 要想让
temp()
得到遍历中的每次ele
的值,就可以通过默认参数的方式,让temp()
在遍历的过程中就得到ele
的值。(这也许是目前唯一的办法)
其实表述的不是很准确:python中所有对变量的赋值操作实质上都是对对象的引用的修改。
在上述行为中,也就是不断改变t
的引用。t = ele = num(obj)
.ele
每次引用不同的对象,而t
总是做与ele
相同的引用。
阅读全文
0 0
- python:工厂函数应该全部设置默认参数
- Python split()函数默认参数
- Python split()函数默认参数
- Python函数默认参数值
- Python进阶-函数默认参数
- Python函数的默认参数
- Python定义函数默认参数
- python 函数默认参数值、关键参数
- 你应该知道的那些超时设置或默认参数
- 你应该知道的那些超时设置或默认参数
- 你应该知道的那些超时设置或默认参数
- 【python】函数:函数文档、关键字参数、默认参数、收集参数
- 函数调用时设置默认参数
- js 函数设置默认参数值
- python 函数默认参数的问题
- 谈谈Python函数的默认参数
- python核心编程-默认函数对象参数
- [Python]默认函数参数注意点
- 操作 java基础心得(3)_多线程(2)
- Effective Modern C++ 笔记(三)——一些关键字
- Sub
- 树
- test
- python:工厂函数应该全部设置默认参数
- 02-GameObject类
- mt7620 openwrt编译,修改dts文件
- [leetcode]606. Construct String from Binary Tree
- 2017 计蒜客 第五场
- Leecode-Remove Duplicates from Sorted Array
- Java-Unsafe类(一)
- Mac下利用Eclipse编写C/C++
- 文章标题