在Python中“准确而优雅”的声明函数(二)
点击关注我哦
一篇文章带你了解函数声明时的优雅操作
4. 错误使用默认值
在编写函数时,Python允许我们为某些参数设置一些默认值。许多内置函数也使用此功能。考虑下面的示例。我们可以使用range()函数创建一个列表对象,该函数具有常规语法range(start,stop,step)。如果省略,默认步骤参数将使用一个。但是,我们可以在以下代码中显式设置step参数(类似于第2个示例):
>>> list(range(5, 15))
[5, 6, 7, 8, 9, 10, 11, 12, 13, 14]>>> list(range(5, 15, 2))
[5, 7, 9, 11, 13]
但是,当我们编写包含具有可变数据类型的默认值的函数时,事情会变得棘手。当我们说可变数据时,是指Python对象在创建后就可以更改,例如列表,字典和集合。要了解有关Python数据可变性的更多信息,请参阅我的上一篇文章。考虑以下有关在函数中使用默认值和可变参数的简单示例:
>>> def append_score(score, scores=[]):
... scores.append(score)
... print(scores)
...
>>> append_score(98)
[98]
>>> append_score(92, [100, 95])
[100, 95, 92]
>>> append_score(94)
[98, 94]
当我们尝试附加分数98时,将打印出预期结果,因为我们省略了分数参数,并且期望使用空列表。当我们尝试将得分92附加到[100,95]列表中时,结果[100,95,92]也符合预期。但是,当我们尝试附加分数94时,我们中的某些人可能会期望结果为[94],但事实并非如此。为什么会发生这种情况?
这是因为Python中的函数也是一等公民,并且被视为常规对象(请参阅我之前的文章,关于函数是Python中的对象)。这意味着在定义函数时,将创建一个对象,包括该函数的默认变量。让我们看一下有关这些概念的代码片段:
>>> def append_score(score, scores=[]):
... scores.append(score)
... print(f'scores: {scores} & id: {id(scores)}')
...
>>> append_score.__defaults__
([],)
>>> id(append_score.__defaults__[0])
4650019968
>>> append_score(95)
scores: [95] & id: 4650019968
>>> append_score(98)
scores: [95, 98] & id: 4650019968
我们修改了先前的功能,使其能够输出分数列表的内存地址。如您所见,在调用函数之前,我们可以找到函数参数的默认值及其访问__default__属性的内存地址。两次调用函数后,具有相同存储地址的相同列表对象已更新。
那么最好的做法是什么?我们应该使用None作为可变数据类型的默认值,这样,在声明函数时,函数不会实例化可变对象。调用函数时,我们可以根据需要创建可变对象。有关其他信息,请参见下面的代码。现在,一切都按预期工作:
>>> def append_score(score, scores=None):
... if not scores:
... scores = []
... scores.append(score)
... print(scores)
...
>>> append_score(98)
[98]
>>> append_score(92, [100, 95])
[100, 95, 92]
>>> append_score(94)
[94]
5. 滥用* args和** kwargs
Python允许我们通过支持可变数量的参数来编写灵活的函数。如果您还记得的话,您一定已经在某些库的文档中的某些地方看到了* args和* kwargs。本质上,* args指的是数量不确定的位置参数,而** kwargs指的是数量不确定的关键字参数。
在Python中,位置参数是根据其位置传递的参数,而关键字参数是根据其指定的关键字传递的参数。下面来看一个简单的例子:
>>> def add_numbers(num0, num1, num2=2, num3=3):
... outcome = num0 + num1 + num2 + num3
... print(f"num0={num0}, num1={num1}, num2={num2}, num3={num3}")
... return outcome
...
>>> add_numbers(0, 1)
num0=0, num1=1, num2=2, num3=3
6
>>> add_numbers(0, 1, num3=4, num2=5)
num0=0, num1=1, num2=5, num3=4
10
在函数add_numbers中,num0和num1是位置参数,而num2和num3是关键字参数。需要注意的一件事是,您可以更改关键字参数之间的顺序,但不能更改位置参数和关键字参数之间的顺序。
尽管* args和* kwargs的可用性使我们能够编写更灵活的Python函数,但是滥用它们可能会导致函数混乱。之前,我提到我们可以使用pandas库进行数据处理,并简要提到了read_csv函数,该函数读取CSV文件。该函数共有49个参数:一个位置参数和48个关键字参数。从理论上讲,我们可以通过执行以下操作使列表更短:
pandas.read_csv(filepath_or_buffer: Union[str, pathlib.Path, IO[~AnyStr]], **kwargs)
但是,在此功能的实际实现中,我们仍然必须拆开* kwarg文件,并弄清楚如何正确读取CSV文件。为什么这些经验丰富的Python开发人员愿意列出所有这些关键字参数?这是因为他们了解以下原则:
“Explicit is better than implicit.” —The Zen of Python
尽管使用** kwargs可以为我们在函数声明的第一行中节省一些时间,但代价是我们的代码变得不太明确。 同样的想法也适用于* args。 如上所述,如果我们在代码共享环境中工作,我们总是希望我们的代码是显式的,从而易于理解。 因此,我们尽可能避免使用* args和** kwargs编写更明确的代码。
总结
在本文中,我们回顾了Python程序员可能在其代码中犯的五个常见错误。 尽管您可以通过忽略项目中的这些错误来拥有自己的编码风格,但是您的代码可能变得难以理解,并且长期可维护性较低。 因此,如果可能的话,我们所有人都可能希望避免这些错误并提高代码的可读性,从而提高共享性。
· END ·
HAPPY LIFE
在Python中“准确而优雅”的声明函数(二)相关推荐
- 在Python中“准确而优雅”的声明函数(一)
点击关注我哦 一篇文章带你了解函数声明时的优雅操作 函数是所有程序的关键组成部分,正确的函数是一种编写可读且可维护的代码的实用方法.但是未正确声明函数,则将把代码将变得难以阅读,并且长期可维护性很低. ...
- python中变量不需要事先声明_第二章 Python 变量
2.1 Python变量 在 Python 中变量不需要事先声明变量名及其类型,直接赋值即可创建各种变量(不要使用关键字为变量名),例如: >>>x = 4 >>> ...
- python中的变量不需要声明
python中的变量不需要声明. 每个变量在使用前都必须赋值,变量复制以后该变量才会被创建.在Python中,变量就是变量,它没有类型, 我们所说的"类型"是变量所指的内存中对象的 ...
- python关键字define_在Python中,使用关键字define定义函数。
在Python中,使用关键字define定义函数. 以下属于生药学有效性评价的是A:有效成分定量分析B:限量检查C:重金属检测D:基原鉴定 若有如下定义和语句:A:7B:12C:8D:9 图示电路中的 ...
- python中的map,feilter,和reduce函数
python中的map,feilter,和reduce函数 map() map()的原型是map(function, iterable, -) 参数 function: 传的是一个函数名,可以是pyt ...
- 从Python中的另一个文件调用函数
本文翻译自:Call a function from another file in Python Set_up: I have a .py file for each function I need ...
- python列表去重函数_对python中两种列表元素去重函数性能的比较方法
测试函数: 第一种:list的set函数 第二种:{}.fromkeys().keys() 测试代码: #!/usr/bin/python #-*- coding:utf-8 -*- import t ...
- python命名规则数字开头的成语_浅谈Python中带_的变量或函数命名
搜索热词 Python 的代码风格由 PEP 8 描述.这个文档描述了 Python 编程风格的方方面面.在遵守这个文档的条件下,不同程序员编写的 Python 代码可以保持最大程度的相似风格.这样就 ...
- Python中求最大值和最小值max()函数、min()函数
[小白从小学Python.C.Java] [Python全国计算机等级考试] [Python数据分析考试必会题] ● 标题与摘要 Python中求最大值和最小值 max()函数.min()函数 ● 选 ...
最新文章
- 怎么看电脑电源多少w_电脑电源供电不足会怎么样 电脑电源供电不足坏处介绍【详解】...
- hdu1255 扫描线,矩形重叠面积(两次以上)
- 事务对性能影响_MySQL数据库性能优化史诗级大总结
- 野蛮愚昧的词过滤,咱是技术网站吗?
- 安装Visio2010 64bit时提示不能安装32位版本的Office 2010 ,因为您当前已经安装了64位Office产品的解决方法(亲测可行)
- IGBT简介、结构及原理
- GRE填空词汇专项训练
- Iframe用法总结
- DIM抠图网络 Deep Image Matting 论文笔记
- Web 服务器配置和管理
- XFire野猪书-XFire开发指南第二版
- Linux nodejs 安装以及配置环境
- FPGA 20个例程篇:9.DDR3内存颗粒初始化写入并通过RS232读取(下)
- iOS常见面试题总结
- 刘顺琦 - CSCI 561 mid 1definition
- 关于keil编译显示Flash Download failed -Could not load file xxxx.axf
- C++各大有名库的介绍(一)
- arp欺骗和dns欺骗
- js获取当前日期及下一天日期
- 一起学英语第二季第六期