广告
返回顶部
首页 > 资讯 > 后端开发 > Python >Python进阶-函数默认参数(详解)
  • 721
分享到

Python进阶-函数默认参数(详解)

进阶详解函数 2022-06-04 18:06:18 721人浏览 薄情痞子

Python 官方文档:入门教程 => 点击学习

摘要

一、默认参数 python为了简化函数的调用,提供了默认参数机制: def pow(x, n = 2): r = 1 while n > 0: r *= x n -= 1

一、默认参数

python为了简化函数的调用,提供了默认参数机制:


def pow(x, n = 2):

  r = 1
  while n > 0:
    r *= x
    n -= 1
  return r

这样在调用pow函数时,就可以省略最后一个参数不写:


print(pow(5)) # output: 25

在定义有默认参数的函数时,需要注意以下:

必选参数必须在前面,默认参数在后;

设置何种参数为默认参数?一般来说,将参数值变化小的设置为默认参数。

python标准库实践

python内建函数:


print(*objects, sep=' ', end='n', file=sys.stdout, flush=False)

函数签名可以看出,使用print('hello Python')这样的简单调用的打印语句,实际上传入了许多默认值,默认参数使得函数的调用变得非常简单。

二、出错了的默认参数

引用一个官方的经典示例地址 :


def bad_append(new_item, a_list=[]):
  a_list.append(new_item)
  return a_list

print(bad_append('1'))
print(bad_append('2'))

这个示例并没有按照预期打印:


['1']
['2']

而是打印了:


['1']
['1', '2']

其实这个错误问题不在默认参数上,而是我们对于及默认参数的初始化的理解有误。

三、默认参数初始化

实际上,默认参数的值只在定义时计算一次,因此每次使用默认参数调用函数时,得到的默认参数值是相同的。

我们以一个直观的例子来说明:


import datetime as dt
from time import sleep


def log_time(msg, time=dt.datetime.now()):

  sleep(1) # 线程暂停一秒
  print("%s: %s" % (time.isofORMat(), msg))

log_time('msg 1')
log_time('msg 2')
log_time('msg 3')

运行这个程序,得到的输出是:


2017-05-17T12:23:46.327258: msg 1
2017-05-17T12:23:46.327258: msg 2
2017-05-17T12:23:46.327258: msg 3

即使使用了sleep(1)让线程暂停一秒,排除了程序执行很快的因素。输出中三次调用打印出的时间还是相同的,即三次调用中默认参数time的值是相同的。

上面的示例或许还不能完全说明问题,以下通过观察默认参数的内存地址的方式来说明。

首先需要了解内建函数id(object) :

id(object)
Return the “identity” of an object. This is an integer which is guaranteed to be unique and constant for this object during its lifetime. Two objects with non-overlapping lifetimes may have the same id() value.

CPython implementation detail: This is the address of the object in memory.

即id(object)函数返回一个对象的唯一标识。这个标识是一个在对象的生命周期期间保证唯一并且不变的整数。在重叠的生命周期中,两个对象可能有相同的id值。
在CPython解释器实现中,id(object)的值为对象的内存地址。

如下示例使用id(object)函数清楚说明了问题:


def bad_append(new_item, a_list=[]):
  
  print('address of a_list:', id(a_list))
  a_list.append(new_item)
  return a_list

print(bad_append('1'))
print(bad_append('2'))

output:


address of a_list: 31128072
['1']
address of a_list: 31128072
['1', '2']

两次调用bad_append,默认参数a_list的地址是相同的。

而且a_list是可变对象,使用append方法添加新元素并不会造成list对象的重新创建,地址的重新分配。这样,‘恰好'就在默认参数指向的地址处修改了对象,下一次调用再次使用这个地址时,就可以看到上一次的修改了。

那么,出现上述的输出就不奇怪了,因为它们本来就是指向同一内存地址。

四、可变与不可变默认参数

当默认参数指向可变类型对象和不可变类型对象时,会表现出不同的行为。

可变默认参数 的表现就像上诉示例一样。

不可变默认参数

首先看一个示例:


def immutable_test(i = 1):
  print('before operation, address of i', id(i))
  i += 1
  print('after operation, address of i', id(i))
  return i
  
print(immutable_test())
print(immutable_test())

Output:


before operation, address of i 1470514832
after operation, address of i 1470514848
2
before operation, address of i 1470514832
after operation, address of i 1470514848
2

很明显,第二次调用时默认参数i的值不会受第一次调用的影响。因为i指向的是不可变对象,对i的操作会造成内存重新分配,对象重新创建,那么函数中i += 1之后名字i指向了另外的地址;根据默认参数的规则,下次调用时,i指向的地址还是函数定义时赋予的地址,这个地址的值1并没有被改变。

其实,可变默认参数和不可变默认参数放在这里讨论并没太大的价值,就像其他语言中所谓的值传递还是引用传递一样,不只会对默认参数造成影响。

五、最佳实践

不可变的默认参数的多次调用不会造成任何影响,可变默认参数的多次调用的结果不符合预期。那么在使用可变默认参数时,就不能只在函数定义时初始化一次,而应该在每次调用时初始化。

最佳实践是定义函数时指定可变默认参数的值为None,在函数体内部重新绑定默认参数的值。以下是对上面的两个可变默认参数示例最佳实践的应用:


def Good_append(new_item, a_list = None):

  if a_list is None:
    a_list = []

  a_list.append(new_item)
  return a_list

print(good_append('1'))
print(good_append('2'))
print(good_append('c', ['a', 'b']))

import datetime as dt
from time import sleep

def log_time(msg, time = None):

  if time is None:
    time = dt.datetime.now()

  sleep(1)
  print("%s: %s" % (time.isoformat(), msg))

log_time('msg 1')
log_time('msg 2')
log_time('msg 3')

以上这篇Python进阶-函数默认参数(详解)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持编程网。

--结束END--

本文标题: Python进阶-函数默认参数(详解)

本文链接: https://www.lsjlt.com/news/13254.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Python进阶-函数默认参数(详解)
    一、默认参数 python为了简化函数的调用,提供了默认参数机制: def pow(x, n = 2): r = 1 while n > 0: r *= x n -= 1...
    99+
    2022-06-04
    进阶 详解 函数
  • Python中的默认参数详解
    文章的主题 不要使用可变对象作为函数的默认参数例如 list,dict,因为def是一个可执行语句,只有def执行的时候才会计算默认默认参数的值,所以使用默认参数会造成函数执行的时候一直在使用同一个对象,引起bug。 基本原理 在 ...
    99+
    2023-01-31
    详解 参数 Python
  • C++函数的默认参数详情
    文章转自微信 公众号:Coder梁(ID:Coder_LT) C++当中的支持默认参数,如果你学过Python,那么想必对此不会陌生。C++中的默认参数的用法和Python基本一致...
    99+
    2022-11-12
  • C++之默认参数详解
    目录一、C++ 默认参数1.举例1.单个参数2.多个参数2.规则总结一、C++ 默认参数 通常情况下,函数在调用时,形参从实参那里取得值。对于多次调用同一函数同一实参时,C++给出了...
    99+
    2022-11-12
  • C++超详细讲解函数参数的默认值
    目录1.参数默认值的指定方式2.参数默认值的指定规则1.参数默认值的指定方式 在 C++ 中,可以在函数声明时为参数提供一个默认值。这样在函数调用时,如果没有提供函数参数值,则使用默...
    99+
    2022-11-13
  • Python函数默认参数如何设置
    这篇文章主要介绍“Python函数默认参数如何设置”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Python函数默认参数如何设置”文章能帮助大家解决问题。我们知道,在调用函数时如果不指定某个参数,P...
    99+
    2023-07-05
  • python函数的默认参数请勿定义可变类型详解
    目录函数的默认参数请勿定义可变类型可变类型和不可变类型定义可变类型会有什么问题?导致的原因解决方法关于可变类型作为默认参数时的注意点测试:将可变类型列表换为字典测试:来个不可变类型字...
    99+
    2022-11-13
  • 深入JS函数中默认参数的使用详解
    目录ES5中的默认参数全新默认参数的诞生默认位置默认参数对函数的length属性的影响重新创建的默认参数默认参数与形参的结合使用默认参数的作用域问题默认参数的隐藏性死区(隐藏的暂时性...
    99+
    2022-11-13
  • Python中的函数参数(位置参数、默认参数、可变参数)
    目录一、位置参数二、默认参数三、可变参数四、关键字参数五、命名关键字参数六、各种参数之间的组合函数的参数:Python中函数定义非常简单,由于函数参数的存在,使函数变得非常灵活应用广...
    99+
    2022-11-12
  • Python 默认参数值
    Python 默认参数值,对于一些函数来说,你可能为希望使一些参数可选并使用默认的值,以避免用户不想为他们提供值的情况。默认参数值可以有效帮助解决这一情况。你可以通过在函数定义时附加一个赋值运算符(=)来为参数指定默认参数值。 要注意到,...
    99+
    2023-01-31
    参数 Python
  • python函数默认参数使用避坑指南
    目录引言verify 炸弹测试接口的数据原因改进方案引言 阿刁是一个自动化测试用例,从一出生他就被赋予终生使命,去测试一个叫登录的过程是否合理。他一直就被关在一个小黑屋里面,从来也没...
    99+
    2022-11-11
  • python默认参数陷阱
    对于学习python的人都有这样的困惑   def foo(a=[]): a.append(5) return a Python新手希望这个函数总是返回一个只包含一个元素的列表:[5]。结果却非常不同,而且非常惊人(对...
    99+
    2023-01-31
    陷阱 参数 python
  • ES6中函数参数的默认值
    小编给大家分享一下ES6中函数参数的默认值,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!函数参数的默认值形参初始值function add(a, b, c&n...
    99+
    2022-10-19
  • golang给函数参数设置默认值的几种方式小结(函数参数默认值
    目录前言强制改变使用可变参数语法糖利用结构体的config转换函数的全部参数补充知识:Golang中设置函数默认参数的优雅实现总结前言 这个问题相当麻烦,根据golang-nuts/...
    99+
    2023-01-06
    golang 参数默认值 golang函数参数设置默认值 golang函数定义
  • 深入讲解Python函数中参数的使用及默认参数的陷阱
    C++里函数可以设置缺省参数,Java不可以,只能通过重载的方式来实现,python里也可以设置默认参数,最大的好处就是降低函数难度,函数的定义只有一个,并且python是动态语言,在同一名称空间里不能有想...
    99+
    2022-06-04
    参数 函数 陷阱
  • Python函数默认参数设置的具体方法
    我们知道,在调用函数时如果不指定某个参数,Python 解释器会抛出异常。为了解决这个问题,Python 允许为参数设置默认值,即在定义函数时,直接给形式参数指定一个默认值。这样的话...
    99+
    2023-05-14
    Python函数默认参数 python 默认参数
  • C++函数的默认参数有哪些
    本篇内容介绍了“C++函数的默认参数有哪些”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!C++当中的支持默认参数,如果你学过Python,那...
    99+
    2023-06-25
  • Python 函数教程:如何使用默认参数和关键字参数?
    函数是 Python 中最基本的编程元素之一,可以将一段逻辑代码封装成一个可重复利用的单元。在 Python 中,函数定义的格式如下: def function_name(parameters): """docstring""" ...
    99+
    2023-06-29
    函数 教程 关键字
  • python中函数默认值使用注意点详解
    当在函数中定义默认值时,值初始化只会进行一次,就是执行到def methodname时执行。看下面代码: from datetime import datetime def test(t=datet...
    99+
    2022-06-04
    详解 函数 默认值
  • 关于Python函数参数的进阶用法
    目录1、关键字参数和位置参数(1)关键字参数(2)位置参数2、接受任意数量的参数(1)接受任意数量的位置参数 (2)接受任意数量的关键字参数(3)同时接受任意数量的位置参数和关键字参...
    99+
    2022-11-12
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作