对Python参数类型详解以及学习中遇到的坑
由于之前遇到过几次有关于参数类型的坑,以及经常容易把一些参数类型搞混淆,现在做一下有关参数类型的总结记录以及对之前踩坑经历的分析。
参数类型
首先我们列举一下有关于Python的参数类型,以及实际上的运用和原理:
- 位置参数(必选参数)
- 默认参数
- 可变参数
- 关键字参数
位置参数(必选参数)
首先是位置参数,同时也被称作必选参数,位置参数很好理解,只要记住这点:
在函数定义时直接给定的此参数名称,调用时按照参数的位置顺序,依次赋予参数值
示例:
def person_info(name, age):print("My name is %s, I am %s years old" % (name, age))person_info("zhangsan", "49")
name,age都是位置参数,按照位置顺序,函数中依次接收参数值。
默认参数
默认参数,默认参数存在许多便利的地方,但是同时也存在许多坑,等到后面我们再去仔细分析下为什么存在这些坑,以下几点我们需要注意的:
- 可以为一个或者多个参数指定默认值,当调用函数时可以不用传入该参数值,大大降低函数调用的难度。
- 当需要用传入的参数值代替默认参数的默认值时,可以按照参数位置顺序传入,同时也可以指定参数名传入。
示例:
'''
学习中遇到问题没人解答?小编创建了一个Python学习交流QQ群:531509025
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
def person_info(name, age, sex='man'):print("My name is %s, I am %s years old, I am %s" % (name, age, sex))person_info('zhangsan', '15')
person_info('lisi', '15', 'women')
person_info('lisi', '20', sex='women')
可变参数
可变参数,顾名思义就是传入的参数数量是可变的:
- 可变参数在实际中,传入的数量可以是任意多个,但也可以没有;
- 而可变参数会在传入函数内部时,是一个tuple的形式;
示例:
def add(*numbers):sum = 0for i in numbers:sum+=ireturn sumprint(add(1,3,4,2,1,4,1,3)) numbers=[2,3,4,1,5]
add(*numbers)
当传入的参数为list时,会将list中所有的元素作为可变参数,传进去
关键字参数
- 关键字参数也允许你传入0个或者任意个含参数名的参数,这些关键字参数会函数内部自动组装为一个dict。
- 调用函数时,可以只传入必选参数。(扩展函数的功能,**kwargs)
示例:
'''
学习中遇到问题没人解答?小编创建了一个Python学习交流QQ群:531509025
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
def person_info(**kw):for key,value in kw.items():print(key, value)person_info(name='zhangsan', age=15)
person = {'name': 'zhangsan', 'age': 13}
person_info(**person)
命名关键字参数
对于关键字参数,函数的调用者可以传入任意不受限制的关键字参数。但是针对到底传入了哪些参数,就需要通过函数内部分析检查。所以命名关键字参数就是限制传入的参数的名字,只能传我已命名关键字参数。
- 命名关键字参数需要一个特殊分隔符*,分隔符后面的参数会被视为命名关键字参数。
- 当函数中已经存在一个可变参数,后面跟着的命名关键字参数就不需要一个特殊分隔符*。
- 命名关键参数可以有默认值,从而简化调用。
- 命名关键参数必须传入一个参数名,这和位置参数不同。如果没有传入参数名,调用将会报错。
示例:
def person_info(name, *, age, sex):print(name, age, sex)def person_info2(name, *args, age, sex):for i in args:print(i)print(name, age, sex)person_info('zhangsan', age=12, sex='man')
person_info2('zhangsan', 'sksks', 'ssk', age=13, sex='man')
参数组合调用规则
在python定义函数过程中,可以用位置参数、默认参数、可变参数、关键字参数、命名关键字参数。这五种参数都可以通过组合使用。需要注意的是:
这五种参数定义的顺序必须是:位置参数、默认参数、可变参数、命名关键字参数、关键字参数。
- 位置参数和默认参数组合
def Person(name, age=20):print(name,age)Person('zhangsan')
Person('zhangsan', 20)
- 位置参数、默认参数、可变参数组合
'''
学习中遇到问题没人解答?小编创建了一个Python学习交流QQ群:531509025
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
def Person(name, age=20, *args):for i in args:print(i)print(name, age)Person('zhangsan')
Person('zhangsan', 22, "Beijing")
Person('zhangsan', age=22, 'Shanghai')
- 位置参数、默认参数、可变参数、命名关键字参数组合
def Person(name, age=20, *args, city, **kwargs):for i in args:print(i)for key,value in kwargs.items():print(key, value)print(name, age, city)Person('zhangsan', age=12, 'Author', city='Shanghai', company='Shanghai Software')
关于参数定义的一些坑
- 默认参数陷阱
关于默认参数陷阱的问题,我们先来看一看一个示例:
def Book(book, book_list=[]):print(id(book_list))book_list.append(book)for book in book_list:print(book)print(id(book_list)) test = Book("First One")
输出的结果:
140699715685128
First One
140699715685128
这个输出的结果应该是意料之中,现在我们这时候再调用Book()方法,看看会发生什么:
>>> test = Book("First One")
140699715685128
First One
140699715685128
>>> test2 = Book("Second One")
140699715685128
First One
Second One
140699715685128
这时候输出结果,竟然把之前的First one都输出,看了他们的id,发现都是同一块内存地址,这时候就开始纳闷了,那么来找找出现这种状况的原因。 经过查阅官方资料发现,这是一段Python官方文档给出的解释:
Important warning: The default value is evaluated only once. This
makes a difference when the default is a mutable object such as a
list, dictionary, or instances of most classes. For example, the
following function accumulates the arguments passed to it on
subsequent calls:
我们来看看解释分析下,Python官方文档给出的理由就是Python对默认值只计算一次,对于可变对象,在后续调用的情况下会累积传递给他们。而list、dict等这种都属于可变对象。
那么对于中默认值陷阱,我们是该如何避免造成一些不必要的麻烦呢?大致有两种解决方法:
- 避免使用可变对象作为默认值
- 在参数定义的时候可以使用None对象作为占位符。
第二种解决方法:
'''
学习中遇到问题没人解答?小编创建了一个Python学习交流QQ群:531509025
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
def Book(book, book_list=None):print(book_list)if book_list is None:book_list = []book_list.append(book)for book in book_list:print(book)print(id(book_list)) test1 = Book('First one')
test2 = Book('Second one')
测试结果:
>>> test1 = Book('First one')
None
First one
140057693903624
>>> test2 = Book('Second one')
None
Second one
140057693903624
- 慎用变长参数
前面已经介绍过了,Python是支持可变长度的参数列表,可以在函数定义参数时使用*args和**kwargs两个特殊的语法来实现。 那为什么要说慎用变长参数,我总结了一下有以下几个原因:
- 使用过于灵活。比如在我上面有关不同类型参数组合使用的示例中,在位置参数和默认参数在的情况下,还有可变参数、关键字参数、命名关键字参数。这就很容易是的这个函数的签名不够清晰,调用者需要花费时间去了解你这个方法该如何调用。所以这就很容易使得团队开发中效率低效。
- 另外一个原因,如果一个函数的列表过于长,虽然可以通过使用*args, **kwargs来简化函数,但同时也意味这个函数或许有更好的实现方式,有重构的必要。
说完了要慎用,在说说看我们常用的变长参数的使用场景:
- 为函数添加一个装饰器。
- 如果参数的数目不确定的时候,可以考虑使用变长参数。比如读取一些配置文件中的配置项时。
- 用来实现函数的多态,或者在继承情况下子类需要调用父类的某些方法。
总结
关于的Python参数类型就写到这里了,刚开始学Python的时候,经常被函数定义的参数类型搞懵,后面看了一些教程,自己在写一些脚本的时候遇到的一些坑,并且在看一些大牛分析背后的原理,后面感觉收获良多。后面干脆想把自己学习过程遇到的东西都整理一下,做个记录,加深理解。
对Python参数类型详解以及学习中遇到的坑相关推荐
- 独热编码python实现_详解深度学习中的独热编码
很多人开始接触深度学习,数据处理遇到第一个专业英文术语就是one-hot encode(独热编码),很多初学者就会迷茫,这个东西是什么意思,其实说的直白点所谓的独热编码最重要的就是把一组字符串或者数字 ...
- Python元组类型详解
今天继续给大家介绍Python相关知识,本文主要内容是Python元组类型定义.操作及应用. 一.元组类型定义 在Python中,元组类型是一种序列类型的一种,并且一旦创建,就不能够被修改. 元组的创 ...
- python变量类型-Python 变量类型详解
变量存储在内存中的值.这就意味着在创建变量时会在内存中开辟一个空间. 基于变量的数据类型,解释器会分配指定内存,并决定什么数据可以被存储在内存中. 因此,变量可以指定不同的数据类型,这些变量可以存储整 ...
- 【NLP】四万字全面详解 | 深度学习中的注意力机制(四,完结篇)
作者 | 蘑菇先生 知乎 | 蘑菇先生学习记 深度学习Attention小综述系列: 四万字全面详解 | 深度学习中的注意力机制(一) 四万字全面详解 | 深度学习中的注意力机制(二) 四万字全面详解 ...
- 详解深度学习中的Normalization,不只是BN(2)
" 深度神经网络模型训练之难众所周知,其中一个重要的现象就是 Internal Covariate Shift. Batch Normalization 大法自 2015 年由Google ...
- 【NLP】四万字全面详解 | 深度学习中的注意力机制(三)
NewBeeNLP原创出品 公众号专栏作者@蘑菇先生 知乎 | 蘑菇先生学习记 深度学习Attenion小综述系列: 四万字全面详解 | 深度学习中的注意力机制(一) 四万字全面详解 | 深度学习中的 ...
- 【NLP】四万字全面详解 | 深度学习中的注意力机制(二)
NewBeeNLP原创出品 公众号专栏作者@蘑菇先生 知乎 | 蘑菇先生学习记 前情提要:四万字全面详解 | 深度学习中的注意力机制(一) 目前深度学习中热点之一就是注意力机制(Attention ...
- 【人工智能】图文详解深度学习中的卷积神经网络(CNN)
[人工智能]图文详解深度学习中的卷积神经网络(CNN) 概念和原理 为什么要使用卷积神经网络? 卷积神经网络简介 卷积神经网络的数学公式 池化操作: 全连接层: 激活函数 卷积神经网络的 C++ 实现 ...
- Python布尔类型详解
对与错.0和1.正与反,都是传统意义上的布尔类型. 但在Python语言中,布尔类型只有两个值,True与False.请注意,是英文单词的对与错,并且首字母要大写,不能其它花式变型. 所有计算结果,或 ...
最新文章
- element的多级选中_element-ui(Vue.js) 我在做二级select联动时选中值是循环的value怎么解?...
- div滚动到指定位置 vue_【Vue 进阶】从 slot 到无渲染组件
- POJ3585-Accumulation Degree【树形dp,二次扫描与换根法】
- 一个Camel Multicast组件聚合策略问题的解决过程
- 如何写python程序
- 程设课终章:c++使用socket实现bmp图片的传输
- 中级软件设计师刷题笔记
- python从云端服务器读数据_云服务器简单实现Python自动运维
- 什么是DML与DDL
- 手机是如何泄密个人隐私的
- JAVA EXAMPLE
- vue 项目中使 实现粒子动态 背景图
- 【封装】Deviation求方差
- 一张纸的厚度大约是0.08mm,对折多少次之后能达到珠穆朗玛峰的高度(8848.13米)?...
- 计算机画图是什么软件,电脑上画图用什么软件
- 哔哩哔哩 2019秋招编程题---山寨金闪闪
- 建立自己的封装库(一)
- 关于Visio的一些使用技巧
- 目前流行的几种软件的压缩比较
- 安卓开发笔记 2
热门文章
- 【自动化测试】Python 读取 .ini 格式文件
- (原)ubuntu14.04中安装gcc4.9和g++4.9
- [剑指offer]8.重建二叉树
- JS原生---鼠标拖拽
- XenApp Farm:修改密码、退域、更改Farm
- 苹果欲借免费纳米SIM卡技术控制行业标准
- Hibernate里自定义UserType时取不到值的问题
- Ubuntu建立(apache+php+mysql)+phpmyadmin
- opencv imread
- java8 日期转换_Java8日期时间——LocalDateTime的使用以及相互转换