Python中的默认参数值

Python中的函数默认参数 需要注意的是,默认参数的值在函数定义时被计算并保存,而不是在每次调用函数时重新计算。在Python中,函数是一种重要的编程结构,它允许我们封装一段可重复使用的代码,并通过参数来接收不同的输入。在定义函数时,我们可以为参数提供默认值,这些默认值在调用函数时可以被省略。这是因为在函数调用时,参数是按照从左到右的顺序进行匹配的,因此我们必须先提供那些没有默认值的参数。然而,由于默认参数的值在函数定义时被计算并保存,所以在多次调用函数时,我们共享相同的。,然后在函数内部检查参数的值,并在需要时创建一个新的对象。 阅读详情

本文主要内容翻译自:点击打开链接

Python处理默认参数值的方式是少数几个难住Python初学者的问题之一(当然通常也就难住第一次)。

造成这种困惑的主要原因是当你使用一个可变的对象作为默认参数值时,也就是说,这个默认值会在某些时候被修改,比如一个list对象或者一个dictionary对象。
举一个例子:

>>> def function(data=[]):
...     data.append(1)
...     return data
...
>>> function()
[1]
>>> function()
[1, 1]
>>> function()
[1, 1, 1]

可以看到,打印出来的list会变得越来越长。如果你注意一下这个list的Identity,你会发现这个函数一直在返回同样的值:

>>> id(function())
12516768
>>> id(function())
12516768
>>> id(function())
12516768

原因很简单,这个函数在每次调用中,一直在使用同样的对象,我们做的修改是具有“粘行的”。

为什么会发生这样的事儿?
当且仅当默认参数值属于的“def”语句被执行的时候,它们就会被求值。

同时也要注意,在Python中,“def”定义的语句是可执行的,它的默认参数会在相对应的“def”语句环境中被求值。如果你多次运行“def”语句,每次它都会创建新的函数对象(用新计算的默认值)。我们将在下面看到例子。

正确的处理方式是怎样的?
作为一种变通方案,正如其他人提到的那样,使用一个占位符而不是修改这个默认值。None是一个常见的占位符:

def myfunc(value=None):
    if value is None:
        value = []
    # modify value here

如果你需要处理任意对象,包括None,你可以使用一个哨兵对象:

sentinel = object()

def myfunc(value=sentinel):
    if value is sentinel:
        value = expression
    # use/modify value here

在老的代码中,也就是在写“object”之前被介绍到的,你有时候会看到如下这样的写法:

sentinel = ['placeholder']

通常用一个唯一的Identity来创建一个non-false对象;当被求值的时候,[] 每次都会创建一个新的list。

使用可变默认参数的有效方式
最后,应该注意到的是在更高级的Python代码中经常使用这个机制来体现它的优势;例如:如果你想在一个循环中创建一串UI Button,你可能会这样尝试:

for i in range(10):
    def callback():
        print "clicked button", i
    UI.Button("button %s" % i, callback)

不料却发现所有的callback都打印相同的值,在这个例子中最可能就是9. 原因是Python的嵌套域绑定在variable上,而不是object value,所以所有的callback实例都将看到当前 i 这个变量的值(=最后一个值)。要修正这个例子,我们只需使用明确的绑定:

for i in range(10):
    def callback(i=i):
        print "clicked button", i
    UI.Button("button %s" % i, callback)

在“i = i”这部分,绑定参数“i”(一个本地变量)到外部变量“i”的当前值中。

(这里我想提一下,Python中“def”定义的函数其实就是一个对象,我们可以把函数具有的默认参数值理解成这个对象的“类属性”,而当这个属性是可变对象的时候,那么我们所做的操作就会被保留下来。再看下面这个例子:

def bar(a=[]):
     print id(a)
     a = a + [1] #赋值后创建了一个新的对象a
     print id(a)
     return a

>>> bar()
4484370232
4484524224
[1]
>>> bar()
4484370232
4484524152
[1]
>>> bar()
4484370232 # "类属性"一直都没有改变
4484523720 # 总是一个新的对象 
[1]
>>> id(bar.func_defaults[0])
4484370232

这样应该就好理解多了,在下面的例子中还会提到这点。)
还有两个其他的使用场景是本地缓存和记忆化,例如:

def calculate(a, b, c, memo={}):
    try:
        value = memo[a, b, c] # 返回已经计算的值
    except KeyError:
        value = heavy_calculation(a, b, c)
        memo[a, b, c] = value # 更新memo字典
    return value

(在确定类型的递归算法中这是相当好用的)
还有就是,在高度优化的代码中,local name重新绑定到global name上:

import math

def this_one_must_be_fast(x, sin=math.sin, cos=math.cos):
    ...

这种特性是如何工作的?
当Python运行一个”def“语句时,它带来了一些已经准备好的部件(包括为这个函数体编译好的代码和当前的命名空间),而且创建了一些新的函数对象。当它做这些的时候,它也会计算默认参数值。

各种各样的组成元件是这个函数对象的有效属性,我们使用上面提到的函数来演示:

>>> function.func_name
'function'
>>> function.func_code
<code object function at 00BEC770, file "<stdin>", line 1>
>>> function.func_defaults
([1, 1, 1],)
>>> function.func_globals
{'function': <function function at 0x00BF1C30>,
'__builtins__': <module '__builtin__' (built-in)>,
'__name__': '__main__', '__doc__': None}

既然你可以访问这些默认值,那么你也可以修改他们:

>>> function.func_defaults[0][:] = []
>>> function()
[1]
>>> function.func_defaults
([1],)

然而,这不是直接的处理方式,更推荐常规的使用方法。。。
(注意这里”[:]”的用法,举个例子:

>>> a = [x for x in range(8)]
>>> print(id(a))
4320183880
>>> a = a + [11, 12]
>>> print(id(a))
4320210632   #赋了新值后地址变了
>>> a[:] = a + [13, 14]
>>> print(id(a))
4320210632   #同样是赋值但是地址没变
>>> print(a)
[0, 1, 2, 3, 4, 5, 6, 7, 11, 12, 13, 14]

当同一个list在很多地方都在引用的时候,我们对某个做的赋值,应该考虑是否让其他地方也适用)

另外一种重置默认参数的简单方法是重新运行相同的”def“语句。然后Python将为代码对象创建一个新的绑定,计算默认参数的值,赋值这个函数对象到前面同样的变量上。但是赋值的时候,你得清楚的知道你在做什么。

当然,如果你碰巧有这个pieces而不是function,你可以使用 new 模块中的 function 类,来创建你自己的函数对象。

Python中函数的默认值参数和关键参数的使用示例 使用环境:需要先安装PyCharm(请自己百度下载安装),以及然后官网上下载Python 2.7版本,以及Python 3.7版本后,安装在自己的电脑上。 使用步骤: 1、下载解压缩之后,打开PyCharm集成开发环境, 2、然后选择“open”菜单打开项目 3、在IDE中打开test_one.py文件,右键点击“Run test_one”或者直接点击右上角的播放键。 如果一切正常,那么你会在PyCharm控制台中看到运行的效果。 阅读人员:学习Python语言的小白。 目的:帮助理解函数的默认参数和关键参数在Python中的具体使用。 立即下载

相关推荐

RPN 解析

RPN全称是Region Proposal Network,Region Proposal的中文意思是“区域选取”,也就是“提取候选框”的意思,所以RPN就是用来提取候选框的网络; 1. RPN的意义 RPN第一次出现在世人眼中是在Faster RCNN这个结构中,专门用来提取候选框,在RCNN和Fast RCNN等物体检测架构中,用来提取候选框的方法通常是Selective Se

lanran2的博客 10万+

Python——参数函数(默认参数)

Python函数参数中的默认参数

qq_66603712的博客 6280

【数学建模】 进化计算与群体智能

遗传算法(GA)是一种用于优化和搜索问题的启发式算法。它模拟了自然选择的过程,其中个体通过遗传和变异进行繁殖,逐渐进化出更优的解。基本步骤初始化:生成初始种群。适应度评估:评估种群中每个个体的适应度。选择:根据适应度选择个体进行繁殖。交叉:选定个体对进行基因交换,生成新的后代。变异:对一些个体进行基因变异,以增加多样性。迭代:重复评估和繁殖过程,直至达到停止条件。粒子群优化算法(PSO)是一种基于群体智能的优化算法,由Kennedy和Eberhart于1995年提出。其灵感来源于鸟群觅食的行为。

weixin_42914989的博客 1113

Python默认参数详解:核心用法、陷阱案例与最佳实践

默认参数(Default Arguments)是Python函数定义时为参数预设的默认值。当调用函数时若未传递该参数,则使用默认值。核心目的是简化函数调用、提高代码复用性。默认参数在函数定义时初始化,对可变类型会引发意外共享使用None替代可变默认值是黄金法则参数顺序:必选参数 -> 默认参数 -> 可变参数当默认值需要动态生成时,使用工厂模式复杂函数建议使用类型提示明确默认值类型# 带类型提示的最佳实践示例# ...处理逻辑...

燃灯工作室 1230

BevFusion (5):逐行代码详解

论文中给出了Bevfusion的架构图,它的输入是多视角的相机和点云图,经过两个特定的head,分别用于做检测任务和分割任务。图1 Bevfusion 结构图Bevfusion因为有两个模态的输入:多视角相机和点云,所以对应两个分支:相机分支和点云分支。相机分支:输入6个视角的图片后,提取特征,然后经VT(View Transformer)转换之后得到相机的Bev特征。激光雷达分支:输入点云数据,经过Encoder编码得到体素化Lidar特征,然后沿z方向展平,得到Lidar Bev特征。

@bangbang的博客 3714

自动驾驶算法/规划决策控制算法面经汇总、学习路线、面经心得

自动驾驶算法学习路线,面试求职大全

qq_41667348的博客 1万+

Python默认值参数

不可变对象:元组、字符串、int、float、bool…作为参数默认值(切记!示例2:不可变对象作为默认值参数。示例1:可变对象作为默认值参数。可变对象:列表、字典、集合。一句话总结:避免使用。

weixin_44361543的博客 597

会计-合并-5- 增资、处置交易在合报与个报会计处理

摘要:本文系统梳理了股权投资会计处理的四种情形:从交易性金融资产转为权益法或成本法、权益法转成本法、权益法增持。核心原则是区分个报与合报处理,重点关注原投资公允/账面价值的计量差异及损益确认逻辑。对不丧失控制权的股权处置,个报确认投资收益,合报调整资本公积;丧失控制权时,个报需追溯调整权益法核算,合报计算综合投资收益。一揽子交易的特殊处理强调将过渡性差额暂记其他综合收益,最终丧失控制权时转入当期损益。文末通过典型案例演示了不同情境下的具体计算方法。

qq_34047402的博客 466

终于弄懂了Python默认参数

默认参数是指在函数定义时为某些参数赋予默认值。如果调用函数时未提供这些参数的值,Python会使用默认值来执行函数逻辑。def greet(name, message="你好"):print(f"def greet(name , message = "你好") : print(f" {name }!") # 调用函数,未传递message参数 greet("张三") # 输出: 你好, 张三!# 调用函数,传递message参数 greet("李四" , "早上好") # 输出: 早上好, 李四!

分享人工智能领域原创文章 2028

终于找到了!Ubuntu 虚拟机卡死的终极解决方案(如何解决VMware安装Ubuntu24.04桌面进不去、黑屏、虚拟机卡死、显示不全、屏幕闪烁等问题)

终于找到了!Ubuntu 虚拟机卡死的终极解决方案(如何解决VMware安装Ubuntu24.04桌面进不去、黑屏、虚拟机卡死、显示不全、屏幕闪烁等问题)

XiaoqiangClub的博客 1万+

YOLOv11 TensorRT极致加速:C++部署性能优化完全指南

购买即可解锁300+YOLO优化文章,并且还有海量深度学习复现项目,价格仅需两杯奶茶的钱,别人有的本专栏也有!

LXY_LOVE36的博客 118

Python(九十一)函数的参数定义-默认参数值

让我们来定义一个简单的函数,其中一个参数有一个默认值。函数用于打印问候语,默认问候语为"Hello"。参数:- name: 字符串,表示要问候的人的名字。- greeting: 字符串,表示问候语,默认值为"Hello"。name }!") # 调用函数 greet("Alice") greet("Bob" , "Good morning")函数用于打印问候语,默认问候语为"Hello"。参数:- name: 字符串,表示要问候的人的名字。

AnChenliang_1002的博客 1485

【专栏必读】王道考研408计算机组成原理万字笔记使用说明及章节导航

本文是为准备408王道计算机组成原理考试的学生精心整理的万字笔记,涵盖了从计算机系统概述、数据表示和运算到存储系统、指令系统等多个章节的重点内容。本文强调了学习笔记的重要性,并分享了学习建议,如按视频课逻辑记录,建立学科框架。笔记详细记录了每章的关键知识点,包括存储器、CPU、I/O系统的工作原理,还附带了习题和思维导图,旨在帮助考生高效复习。

快乐江湖的博客 9万+

Python 默认参数值

默认参数值 Python 默认参数值,对于一些函数来说,你可能为希望使一些参数可选并使用默认的值,以避免用户不想为他们提供值的情况。默认参数值可以有效帮助解决这一情况。你可以通过在函数定义时附加一个赋值运算符(=)来为参数指定默认参数值。要注意到,python默认参数值应该是常数。更确切地说,默认参数值应该是不可变的——这将在python教程后面的章节中...

weixin_34192993的博客 109

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

python函数把可变数据类型当默认参数值的问题

转自:https://www.cnblogs.com/gpd-Amos/p/8998059.html#_label0 python函数中把列表(list)当参数时的&amp;amp;amp;quot;入坑&amp;amp;amp;quot;与&amp;amp;amp;quot;出坑&amp;amp;amp;quot; 阅读目录入坑出坑优化&amp;amp;amp;amp;nbsp;在Python函数中,传递的参

百雨的博客 2179

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

python 函数默认参数值、关键参数

source:http://hi.baidu.com/yuhc123/item/6086d6dc32092b53d63aae14 默认参数值 对于一些函数,你可能希望它的一些参数是可选的,如果用户不想要为这些参数提供值的话,这些参数就使用默认值。这个功能借助于默认参数值完成。你可以在函数定义的形参名后加上赋值运算符(=)和默认值,从而给形参指定默认参数值。 注意,默认参数值应

tech 1584

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

Python官方3.2文档教程--方法定义-默认参数值

2.7.1 默认参数值 最有用的形式就是给一个或多个变量制定默认值。这种方法可以创建一个允许调用时比定义时需要更少的参数。例如:   def ask_ok(prompt, retries=4, complaint=’Yes or no, please!’): while True: ok = input(prompt) if ok in (’y’, ’ye’, ’yes’): ret

夜深人静后的码农 1477

python函数默认参数_python 函数默认参数值、关键参数 | 学步园

source:http://hi.baidu.com/yuhc123/item/6086d6dc32092b53d63aae14默认参数值对于一些函数,你可能希望它的一些参数是可选的,如果用户不想要为这些参数提供值的话,这些参数就使用默认值。这个功能借助于默认参数值完成。你可以在函数定义的形参名后加上赋值运算符(=)和默认值,从而给形参指定默认参数值。注意,默认参数值应该是一个参数。更加准确的说,...

weixin_39847722的博客 183

Python陷阱:为什么不能用可变对象作为函数的默认参数值

原文链接: Python陷阱:为什么不能用可变对象作为函数的默认参数值 ...

阿豪 57

Python中默认参数值

关于Python默认参数,假如默认参数是可变(mutable)对象是会有副作用的,一个函数参数的默认值,仅仅在该函数定义的时候,被赋值一次。如此,只有当函数第一次被定义的时候,才将参数的默认值初始化到它的默认值(如一个空的列表)如:&gt;&gt;&gt; def function(data=[]): data.append(1) return data &gt;&gt;&gt; funct...

aiwoya213的专栏 5122

python 默认参数值_默认参数值

该楼层疑似违规已被系统折叠隐藏此楼查看此楼最常用的一种形式是为一个或多个参数指定默认值。这会创建一个可以使用比定义时允许的参数更少的参数调用的函数,例如:def ask_ok(prompt, retries=4, complaint='Yes or no, please!'):while True:ok = input(prompt)if ok in ('y', 'ye', 'yes'):ret...

weixin_36258891的博客 685

python基础--函数的形参,默认参数值,列表参数,不定长参数,字典型参数

1,默认参数值:   首先来上段代码: def login(username='abc',password='123'): if username=='admin' and password=='admin123': print('登陆成功') else: print('登录失败') return username...

weixin_30877755的博客 396
上一篇: iOS中自定义进度条设置半透明背景(Swift 3)
下一篇: Python中的函数装饰器
Willib
博客等级 码龄14年 83粉丝 44原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值