1 Python中的函数

  函数,从数学的角度来讲是,输入一个参数,经过一个表达式的处理后得到一个结果的输出,即就是x-->y的一个映射。同样,在Python或者任何编程语言中,函数其实就是实现一种功能,也可以称其为接口,通过使用定义的函数,以此来达到某种功能的实现。

1.1 Python中函数的定义

  使用def语句可定义函数: 

 def 函数名(参数列表)
函数体(代码块)
[return 返回值]

  函数名就是一个函数的名字,也是一种标识符,命名的要求为:只能以字母或下划线开头的除   Python的关键字外的任意字符串,注意Python是大小写敏感的;

  Python中利用缩进的形式来表示语句块,约定4个空格;

  返回语句,在一个函数中可以没有返回值,如果没有返回值,隐式会返回一个None值;

  定义中的参数列表为形式参数,只是一种符号表达,简称形参;

  比如下面的add函数:

 def add(x, y):
return x + y

1.2 函数的调用

  函数的定义过程,只是声明了一个函数,函数不会被执行,需调用。对于1.1中定义的函数,通过a = add(3, 4)来调用,其中调用时写的参数是实际参数,是实实在在传入的值,简称实参。

  函数可调用的对象,可以通过callable()函数来检测一个变量是否可以调用。

2 函数参数

  在Python中函数的参数有以下几种类型:

  •   位置参数
  •   关键字参数
  •   可变参数
  •   keyword-only参数

2.1 位置参数

  在1.1中定义的add(x, y)函数,其中x和y为位置参数。在调用函数的时候,实参的顺序和数量必须与函数定义中的形参匹配,否则会引发TypeError异常。

  比如定义函数def f(x, y, z),调用时为f(1, 2, 3).

2.2 关键字参数

  函数调用的过程当中,实参利用函数形参的名字进行赋值传参,那么该实参就为关键字参数。如果函数调用时的实参使用了形参名字,那么传参顺序就可和定义参数的顺序不同。

  同样对函数的f有以下调用方式:

 f(1, 2, 4)
f(z=None, x=6, y=4) # 关键字参数调用
f(y=5, 2, 6) # 该调用方式是否可行

  注:要求位置参数必须在关键字参数之前传入,位置参数是按位置对应的。

2.3 可变参数

  有时候在调用函数时,可能会给函数传多个参数,我们不可能在定义函数时将函数的参数的个数固定死,那么这个函数的灵活性就不存在。于是就有了可变参数,即一个形参可匹配任意个参数。可变参数分为:位置参数的可变参数和关键字参数的可变参数。

2.3.1 位置参数的可变参数

  在形参前使用*标识该形参是可变参数,可以接收多个实参。如下例子:

 def add(*nums):
sum = 0
print(type(nums))
for x in nums:
sum += x
print(sum)
add(3, 6, 9) # 调用

  调用add函数时的实参为多个,这时形参中的*num会将多个实参收集为一个tuple。

2.3.2 关键字参数的可变参数

  在形参前使用**符号,可以接收多个关键字参数。如下示例:

 def showconfig(**kwargs):
for k,v in kwargs.items():
print('{} = {}'.format(k, v))
showconfig(host='127.0.0.1',port='',username='viktor',password='123456')

  调用showconfig时使用了关键字参数,这时函数中的形参**kwargs会将多个关键字参数收集为一个字典(dict)。

2.3.4 可变参数总结

  可变参数可以接收任意个参数,其中位置可变参数将收集的参数形成一个元组,关键字参数将收集的参数形成一个字典。当然这些参数都可以在函数定义时混合使用,混合使用参数的时候要注意:可变参数要放到参数列表的最后,位置参数放到参数列表的前面,位置可变参数需要放在关键字可变参数之前。如下例子:

 def fn(x, y, *args, **kwargs):
print(x)
print(y)
print(args)
print(kwargs)
fn(3,5,7,9,10,a=1,b='python')
fn(3,5)
fn(3,5,7)
fn(3,5,a=1,b='python')
fn(7,9,y=5,x=3,a=1,b='python') # 错误,7和9分别赋给了x,y,又y=5、x=3,重复了 def fn(*args, x, y, **kwargs):
print(x)
print(y)
print(args)
print(kwargs)
fn(3,5) # 执行出现TypeError
fn(3,5,7) # 执行出现TypeError
fn(3,5,a=1,b='python') # 执行出现TypeError
fn(7,9,y=5,x=3,a=1,b='python')

2.4 keyword-only参数

  keyword-only参数是在Python3中加入的。如果在一个星号参数后,或者一个位置可变参数后,出现普通参数,那么这个参数就为keyword-only参数。示例如下:

 def fn(*args, x):
print(x)
print(args)
fn(3,5)
fn(3,5,7)
fn(3,5,x=7)

  可以看出,在函数调用的过程中,args参数将所有的位置参数截获,x不使用关键字参数就不可能接收到实参的传递。那么,关键字的可变参数后是否能跟一个普通的位置参数呢?看如下示例:

 def(**kwargs, x):
print(x)
print(kwargs)

  运行后直接报语法错误,可以理解为kwargs会截获所有的关键字参数,就算在调用函数时的形参中有类似x = 5形式的传参,形参x也不能得到该值,而这个位置参数上的值又必须在函数调用时提供,所以就会出现语法错误。

  keyword-only参数另一种形式:*号之后跟普通形参,示例如下:

 def fn(*, x,y):
print(x,y)
fn(x=5,y=6)

  *号之后,普通参数都会变成必须给出的keyword-only参数。

2.5 可变参数和参数默认值

  函数的定义中,将参数的默认值和可变参数混合在一起使用,那么函数的调用过程中是如何传参呢?看下面几个示例:

 def fn(y, *args, x=5):
print('x={}, y={}'.format(x, y))
print(args)
fn() # 出错,因为fn函数中的位置参数y在调用fn时必须得给出;
fn(5) # 可以执行,此时形参y接收5,args参数为空,x参数使用默认值;
fn(x=6) # 错误,形参y必须接收一个实参;
fn(1,2,3,x=10) # 可以执行,此时y=1,args=(2, 3),x=10;
fn(y=17,2,3,x=10) # 出现语法错误,调用函数时,必须得将关键字参数放到参数列表的后面
fn(1,2,y=3,x=10) # 出错,形参y已经接收到实参1,之后又利用关键字参数给y进行传参,肯定会出错
 def fn(x=5, **kwargs):
print('x={}'.format(x))
print(kwargs)
fn() # 可以执行,x使用默认值5,kwargs为空
fn(5) # 可以执行,x=5,kwargs为空
fn(x=6) # 可以执行,此时x=6,kwargs为空
fn(y=3,x=10) # x=10,字典中存入'y':3
fn(3,y=10) # x=3,字典中存入'y':10

2.6 函数参数定义规则

  参数列表中的参数的一般顺序是:普通参数、缺省参数、可变位置参数、keyword-only参数(可带缺省值)、可变关键字参数。如下:

 def fn(x, y, z=3, *arg, m=4, n, **kwargs):
print(x,y,z,m,n)
print(args)
print(kwargs)

3 函数参数解构

  给函数提供实参时,可以在集合类型的实参前使用*或者**,把集合类型的结构解开,提取出所有元素作为函数的实参。如下示例:

 def add(x, y):
return x+y add(4, 5)
add((4,5))
t = (4, 5)
add(t[0], t[1])
add(*t)
add(*(4,5))
add(*[4,5])
add(*{4,6})
add(*range(1,3)) d = {'x': 5, 'y': 6}
add(**d)
add(**{'a': 5, 'b': 6})
add(*{'a': 5, 'b': 6}) def add(*iterable):
result = 0
for x in iterable:
result += x
return result
add(1,2,3)
add(*[1,2,3])
add(*range(10))

  参数解构时,非字典类型的实参使用*解构成位置参数;字典类型使用**解构成关键字参数。注意:提取出来的元素数目要和参数的要求匹配,也要和参数的类型匹配。

  

Python函数参数与参数解构的更多相关文章

  1. 函数、可变参数、keyword-only参数、实参解构

    函数的数学定义:y=f(x) ,y是x的函数,x是自变量.y=f(x0, x1, ..., xn) python中的函数: 由函数名称.参数列表.和若干语句组成的语句块构成,完成一定的功能,是组织代码 ...

  2. vuex2.0.0爬坑记录 -- mutations的第一个参数state不能解构

    今天在学习vuex的过程中,遇到了一个很困扰人的问题,最终利用vuex的状态快照工具logger解决了问题. 问题是这样的,我在子组件中使用了mapState()函数来将状态映射至子组件中,使子组件能 ...

  3. python函数中的参数类型

    python函数中的参数 动态获取函数的参数 python的函数类型详解

  4. Python 函数中,参数是传值,还是传引用?

    在 C/C++ 中,传值和传引用是函数参数传递的两种方式,在Python中参数是如何传递的?回答这个问题前,不如先来看两段代码. 代码段1: def foo(arg): arg = 2 print(a ...

  5. Python入门篇-封装与解构和高级数据类型集合(set)和字典(dict)

    Python入门篇-封装与解构和高级数据类型集合(set)和字典(dict) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.封装和结构 #!/usr/bin/env pytho ...

  6. Python函数中的参数(一)

    函数传递参数时的简要关键点: 1.参数的传递是通过自动将对象赋值给本地变量名来实现的.函数参数在实际中只是Python赋值的一个实例.因为引用是以指针的形式实现的,所有的参数实际上都是通过指针进行传递 ...

  7. Python函数中的参数(二)

    当使用混合特定的参数匹配模型时,Python将会遵循以下有关顺序的法则: 1.在函数调用中,参数必须以这样的顺序出现:任何位置参数(Value).任何关键字参数(name = Value)和*sequ ...

  8. Python 函数(可变参数)

    在python函数中,可以定义可变参数,顾名思义,可变参数就是,传入的参数是可变的例如,给定一组数字a,b,c...  请计算a2 + b2 + c2 + …… 要定义出这个函数,我们必须确定输入的参 ...

  9. python 函数传递可变参数的用法

    可变参数 在Python函数中,还可以定义可变参数.顾名思义,可变参数就是传入的参数个数是可变的,可以是1个.2个到任意个,还可以是0个. 我们以数学题为例子,给定一组数字a,b,c……,请计算a2 ...

  10. python函数的万能参数

    我们通过一个简单的事例来展示一下函数的万能参数,我们先写一个最简单的函数 def test(*args,**kwargs): print(args,kwargs) 然后定义两个变量 l = [1,2, ...

随机推荐

  1. CentOS配置服务开机自启

    本例子以nginx作为举例: CentOS7中 以systemctl 替代了chkconfig 进行服务的管理, 默认在CentOS6 中控制服务开机自启,是在vim /etc/rc.d/rc.loc ...

  2. ssh-agent代理的简单用法

    前言 在ansible的官方文档中,提到了强烈推荐用ssh-agent来管理密钥 究竟ssh-agent是什么,它有什么用法呢,下面来一探究竟. ssh-agent是什么?用处是什么? ssh-age ...

  3. Xpath定位和CssSelector定位的区别

    1.Xpath基本语法: (1)"/":从根节点选取,下级节点 (2)"//":任意节点选取 (3)"*":任意标签选取 (4)" ...

  4. fireFox模拟 post请求、上传插件,火狐浏览器中文postman插件

    ApiPost是一个支持团队协作,支持模拟POST.GET.PUT等常见请求,并可直接生成文档的API调试.管理工具. 它拥有以下功能特性: 1.文档管理ApiPost不仅可以快速生成接口文档,还支持 ...

  5. @Qualifier高级应用---按类别批量依赖注入【享学Spring】

    每篇一句 罗斯:选秀状元可能有水货,但MVP绝对没有 前言 在上篇文章(讲解@LoadBalanced负载均衡)的末尾,我抛出了一个很重要的问题,建议小伙伴自己深入思考一番:本文主要针对此问题,作出一 ...

  6. CS中委托与事件的使用-以Winform中跨窗体传值为例

    场景 委托(Delegate) 委托是对存有某个方法的引用的一种引用类型变量. 委托特别用于实现事件和回调方法. 声明委托 public delegate int MyDelegate (string ...

  7. 05.Django基础五之django模型层(一)单表操作

    一 ORM简介 MVC或者MVC框架中包括一个重要的部分,就是ORM,它实现了数据模型与数据库的解耦,即数据模型的设计不需要依赖于特定的数据库,通过简单的配置就可以轻松更换数据库,这极大的减轻了开发人 ...

  8. 《Java核心技术卷1》读书笔记

    一.基础 数据类型 Java是一种强类型语言,一共8种基本类型,没有无符号类型 整型:int(正负20亿).short(正负3万).long(巨多).byte(正负127) 浮点类型:float(正负 ...

  9. AWS加入.NET Foundation企业赞助商计划

    .NET 走向开源,MIT许可协议. 微软为了推动.NET开源社区的发展,2014年联合社区成立了.NET基金会. .NET基金会是一个独立的组织,支持.NET社区和开源,旨在拓宽和加强.NET生态系 ...

  10. 【linux】【gitlab】gitlab安装、备份、恢复、升级、内存消耗问题

    前言 GitLab:GitLab 是一个用于仓库管理系统的开源项目,使用Git作为代码管理工具,并在此基础上搭建起来的web服务.功能:Gitlab 是一个提供代码托管.提交审核和问题跟踪的代码管理平 ...