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相同的引用。

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 还没发货申请退款卖家不处理怎么办 快递写错电话被更改收货信息怎么办 货在派送中快递地址填错了怎么办 老板损坏了你保管的器材怎么办 闲鱼买家说不合适要退货怎么办 日本邮便局的单号我忘了怎么办 小米盒子自带播放器被删除了怎么办 在电视上装了央视影音要升级怎么办 用现金支付货款没有了证据怎么办 楚楚街不发货客服不理人怎么办 厨房那面墙借用别人的怎么办 天猫买东西商家不给发货怎么办 在唯品会上买的水果坏了怎么办 美团极速退款后商家仍然送餐怎么办 我的拼多多商家密码忘了怎么办 特约金服扣款连续扣了两次怎么办? 拼多多拒绝退款联系客服退款怎么办 镇江新设名称申报中字号怎么办 创维电视只有声音没有图像怎么办 京东E卡有密码忘记卡号怎么办? 香香鞋上的饰品老掉怎么办 联壁金融资金冻结提现不出来怎么办 联壁金融提现不到帐怎么办 联壁金融提现迟迟不到帐怎么办 客户说平安福现金价值低怎么办 2个月宝宝肚脐凸出来怎么办 西安华润万家预付卡丢了怎么办 租房签了一年合同想走怎么办 京东寄包裹在速递易里面该怎么办 翼码科技辅助码被删掉了怎么办 用别人的身份证注册的手机号怎么办 大v线做到假线了怎么办 有个摄像头网段不同搜不到怎么办 百度网盘离线下载有违规内容怎么办 抖音上传的照片与音乐不同步怎么办 社保卡里面的钱用完了怎么办 医保卡里面的钱用完了怎么办 手机通知栏变成了搜索栏怎么办 小米手机账号密码忘了手机号怎么办 暑假工没签合同押工资了的怎么办 在日本雅虎拍卖网站买到假货怎么办