Python学习6.1_函数参数及参数传递
大多数编程语言都绕不开一个名词,那就是--函数(function)。而函数很重要的部分则是参数(arguments)的使用。Python的参数传递总体来说是根据位置,传递对应的参数。阐述如下:
1、位置参数及传递:
位置参数:顾名思义位置参数是根据形参的位置先后顺序传入的。
如下:定义一个测试函数,传入三个参数,然后依次打印出这三个参数:
def fun(first, second, third):
print first, second, third if __name__ == '__main__':
fun(21, 'second', [21, 'sum', 'T'])
在调用fun函数时,first, second, third根据各位置相对应的传递给了21, 'second', [21, 'sum', 'T'] 三个不同类型的数据。当然也可以将这些数据写成单独的变量,如下所示,然后将变量按位置顺序传入,这种方式和直接在实参(值)位置按顺序写入是一样的,只不过封装了一下。
def fun(first, second, third):
print first, second, third if __name__ == '__main__':
num1 = 21
num2 = 'second'
num3 = [21, 'sum', 'T']
fun(num1, num2, num3)
输出的结果都是:21 second [21, 'sum', 'T']
位置参数的好处在于我们不需要知道形参长什么样;坏处是需要知道它们有几个,每一个表示什么意思,处在什么位置。位置参数相对而言,比较简单,只需按照位置一一对应传入即可。
2、关键字参数及传递
关键字参数:从意思理解指的是当调用一个函数的时候,可以用key = value的方式来指定给某个具体参数赋值。
由于是根据具体参数名赋值,那么就可以不遵守函数声明里的参数顺序,虽然不用管形参的排列顺序,但参数个数还是需要遵循的。
def fun(first, second, third):
print first, second, third if __name__ == '__main__':
fun(second=21, third='second', first=[21, 'sum', 'T'])
在调用函数fun时,根据形参的字符字段分别被赋值为21, 'second', [21, 'sum', 'T'],虽然三个值以及三个值的顺序都没发生改变,但由于形参关键字的原因已经使得三个值实际对应的顺序已然不同,从打印结果就可以看出
输出的结果:[21, 'sum', 'T'] 21 second
关键字参数的好处在于我们不需要知道形参的具体分布位置,同时明确了每个参数的含义;坏处是必须要知道形参都长啥样。
3、参数默认值
参数默认值:即函数在定义时就为某些形参赋予默认值。在该函数被调用时,若未给这些参数传入值,那么该函数就使用默认值进行计算;若这些参数有传入值,那么默认值就无效,函数使用传入值进行计算。
调用一:如下所示third和fourth在函数定义时分别被赋予默认值None和’today’,调用函数时,按位置参数顺序只传递了两个值。
def fun(first, second, third=None, fourth='today'):
print first, second, third, fourth if __name__ == '__main__':
fun(21, 'second')
输出结果:21 second None today 从结果看出,前两个参数是按位置参数顺序传递的值,后两个参数是默认值
调用二:如下所示third和fourth在函数定义时分别被赋予默认值None和’today’,但是在调用函数时,按位置参数顺序传递方式传递进三个值。
def fun(first, second, third=None, fourth='today'):
print first, second, third, fourth if __name__ == '__main__':
fun(21, 'second', [21, 'sum', 'T'])
输出结果:21 second [21, 'sum', 'T'] today 从结果看出,此次调用third参数值已经被改变为[21, 'sum', 'T'], 默认值无效。仅仅只是此次调用默认值无效,但函数内third设定的默认值依然存在,不会丢失。
参数默认值的好处在于我们可以根据参数在函数内的使用情况默认的赋予初始值,坏处是带有默认值的形参必须在不带默认值的形参后面,即默认值参数必须在位置参数后面。
4、收集参数(包裹参数)及传递
收集参数:将某些位置参数,或者关键字参数打包收集起来,然后使用。在定义函数时,我们有时候并不知道调用函数时需要传入多少个参数,也不知道会传入多少个参数。这时候,收集位置参数,或者收集关键字参数,来进行参数传递,会非常有用。
参数收集函数的定义分为两种,即形参前带“*”或者“**”:
def fun(*data):和def funtion(**bass):
下面定义了def fun(*data):和def funtion(**bass): 两个例子,将数据传入后,分别打印出该参数类型和收集后形成的数据。
def fun(*data):
print type(data)
print data def funtion(**bass):
print type(bass)
print bass if __name__ == '__main__':
fun(21, 'second', [21, 'sum', 'T'], {'num': 100, 'sum': 'num123'})
funtion(feng=23, ling='xue', ying=[1, 2, 'yun'], han={'qiu': 'yu'})
从调用fun()和funtion()时传入的参数可以看出,fun()函数的实参,可以无序,也可以是任何类型,但必须是位置参数格式传入,不能是关键字参数格式传入;而funtion()函数的实参,也可以是无序,也可以是任何类型,但却必须是关键字参数格式传入,不能是位置参数格式。不信的话,可以试试传入其他格式。
输出结果:<type 'tuple'>
(21, 'second', [21, 'sum', 'T'], {'sum': 'num123', 'num': 100})
<type 'dict'>
{'ling': 'xue', 'feng': 23, 'ying': [1, 2, 'yun'], 'han': {'qiu': 'yu'}}
从输出结果得出fun()函数输出的类型是”组”,是元组,也就是说”*”将位置参数收集起来形成了一个包裹(元组);而funtion()函数输出的类型是字典,即”**”将关键字参数收集起来形成另一个包裹(字典)。并且就算两函数不传入任何值,其返回的结果也依然是元组和字典。
如下所示:两函数不变,调用时不传入任何值。
if __name__ == '__main__':
fun()
funtion()
输出结果:<type 'tuple'>
()
<type 'dict'>
{}
也就是说单星号”*”是将参数收集形成一个元组,不论参数数量多少,但限定传入格式是位置参数;双星号”**”是将数据收集成一个字典,同样不论数量多少,但限定传入格式是关键字参数类型。这两种形参的好处是不用限定传入参数的个数和传入的顺序。
5、解包裹参数
定义函数时,在形参名前面加上“*”或者“**”,可以将参数按位置收集起来,分别封包成元组和字典传递。
“*”和“**”,也可以在调用函数的时候使用,即在实参前使用,也就是所谓解包裹。
1、解包元组:定义一个fun()函数,设定四个形参,然后将这四个参数打印出来。调用该函数时传入一个元组,并在元组名前加“*”。形参个数在此是根据调用该函数时传入实参,将实参分解后的板块数设置的(其实这样做不妥,但此处仅为验证解包,故而直接匹配个数)。
def fun(a, b, c, d):
print a, b, c, d if __name__ == '__main__':
data = (21, 'second', [21, 'sum', 'T'], {'num': 100, 'sum': 'num123'})
fun(*data)
输出结果:21 second [21, 'sum', 'T'] {'sum': 'num123', 'num': 100} 从输出结果看出,已经将元组()解封成4个单独的数据。
2、解封字典比较特殊,从下面的形参设定就可以看出,形参和字典里面关键字是一一匹配的,这是特殊之处。
def func(ling, feng, ying, han):
print ling, feng, ying, han if __name__ == '__main__':
data_da = {'ling': 'xue', 'feng': 23, 'ying': [1, 2, 'yun'], 'han': {'qiu': 'yu'}}
func(**data_da)
输出结果:xue 23 [1, 2, 'yun'] {'qiu': 'yu'} 输出结果可以看出,已经将字典解包了,将值都单独呈现出来。
如果定义函数时形参和字典关键字不能一一对应,运行时会报错,如下所示。
def func(xxxx, feng, ying, han):
print xxxx, feng, ying, han if __name__ == '__main__':
data_da = {'ling': 'xue', 'feng': 23, 'ying': [1, 2, 'yun'], 'han': {'qiu': 'yu'}}
func(**data_da)
输出结果:下面报错意思是“定义了一个意外的关键字参数‘ling’”,也就是说字典里面有一个形参不存在的关键字’ling’,可以换其他的试试,一样会报错。
Traceback (most recent call last):
File "E:/python/0531/test02.py", line 12, in <module>
func(**data_da)
TypeError: func() got an unexpected keyword argument 'ling'
所以“*”和“**”不仅能按位置将参数收集起来,打包使用,也可以将包裹解开,按单个值使用。
6、混合
在函数的定义或调用时,参数的几种传递方式可以混合使用。但在过程中要注意前后顺序。基本原则是,先位置,次关键字,再次包裹位置,最后包裹关键字。
定义函数时,若形参类型是位置参数和关键字参数(赋予默认值),那么位置参数必须在关键字参数前面;若形参类型是位置参数和关键字参数以及包裹位置参数,那么形参顺序必须是位置参数,关键字参数,包裹位置参数;若形参类型是位置参数,关键字参数,包裹位置参数以及包裹关键字参数,那么形参顺序必须是位置参数,关键字参数,包裹位置参数,包裹关键字参数。这些形参类型顺序不能颠倒,也不能混乱(颠倒了,语法规则检验都过不了)。如下所示:
def func(data, num=100, *sum, **han):
print type(data), type(num), type(sum), type(han)
print data, num, sum, han if __name__ == '__main__':
func('today', 21, [21, 'sum', 'T'], {'num': 100, 'sum': 'num123'}, feng=23, ying=[1, 2, 'yun'], han={'qiu': 'yu'})
输出结果:
<type 'str'> <type 'int'> <type 'tuple'> <type 'dict'>
today 21 ([21, 'sum'], {'num': 100}) {'feng': 23, 'han': {'qiu': 'yu'}}
注:注意”*”,”**”定义时和调用时的区分。包裹参数和解包裹参数不是相反操作,是两个相对独立的过程。
位置参数和按参数位置收集不同。位置参数,每个参数的位置固定的,个数也是固定的,调用时传入的值和形参的位置是一一对应的;而按参数位置收集,是指带有“*”的形参,它会将除位置参数对应的实参以外,其他参数按传入位置的先后收集成一个元组。
def func(data, num=100, *sum):
func('today', 21, [21, 'sum', 'T'], {'num': 100, 'sum': 'num123'})
除'today', 21是位置参数的实参外,其余实参按参数位置被*sum收集起来,形成一个元组
Python学习6.1_函数参数及参数传递的更多相关文章
- python学习笔记:函数参数
1. 位置参数:一般的参数 2. 默认参数: def power(x, n=2): s = 1 while n > 0: n = n - 1 s = s * x return s 参数里有默认赋 ...
- Python学习手册之 Python 之禅、Python 编程规范和函数参数
在上一篇文章中,我们介绍了 Python 的正则表达式使用示例,现在我们介绍 Python 之禅. Python 编程规范和函数参数.查看上一篇文章请点击:https://www.cnblogs.co ...
- Python学习笔记7-把函数当参数传递、指定可变参数
把函数当参数传递 # 函数参数传递 # 面向对象编程就是把对象传来传去 # 面向函数编程就是把函数传来传去 def mytest(num): return num * 2 # # 不光可以传递变量,还 ...
- python学习道路(day4note)(函数,形参实参位置参数匿名参数,匿名函数,高阶函数,镶嵌函数)
1.函数 2种编程方法 关键词面向对象:华山派 --->> 类----->class面向过程:少林派 -->> 过程--->def 函数式编程:逍遥派 --> ...
- python学习笔记(3)--函数、参数、变量、递归
1.函数基本语法和特性 背景摘要 现在老板让你写一个监控程序,监控服务器的系统状况,当cpu\memory\disk等指标的使用量超过阀值时即发邮件报警,你掏出了所有的知识量吗,写出了以下代码 whi ...
- Python 学习:常用函数整理
整理Python中常用的函数 一,把字符串形式的list转换为list 使用ast模块中的literal_eval函数来实现,把字符串形式的list转换为Python的基础类型list from as ...
- 【Python学习之五】函数
环境 虚拟机:VMware 10 Linux版本:CentOS-6.5-x86_64 客户端:Xshell4 FTP:Xftp4 python3.6 Python不但能非常灵活地定义函数,而且本身内置 ...
- python学习之---匿名函数,返回函数,偏函数
1. 返回函数: 所谓的返回函数,指的是函数作为返回值.高阶函数除了可以接受函数作为参数外,同样可以接受函数作为结果返回.以下是一个可变参数的求和例子,一般求和函数是如此这般定义的: >> ...
- Python学习---高阶函数的学习
高阶函数 高阶函数:函数名可以作为参数传递输入,函数名还可以作为返回值返回 函数名可以重新赋值,因为其本身就是一个变量 函数本身就是一个对象, 函数的变量名f本身就是指向函数本身的,加上括 ...
随机推荐
- java JDK安装
JDK安装包下载地址:http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html 图释安装 ...
- [Locked] Binary Tree Vertical Order Traversal
Binary Tree Vertical Order Traversal Given a binary tree, return the vertical order traversal of its ...
- D - How Many Answers Are Wrong(hdu 3038)
总算碰到一道不那么无聊的题了^^ 先说一下题意吧,有两个人一个叫TT的男孩一个叫FF的女孩(名字太随意了吧....),这个叫TT的男孩会经常叫这个女孩一起玩一个游戏,这个有些是这样的,随便写一个数列, ...
- poj1065
题目大意: 木棍(好吧,承认确实做过这个题,嘎嘎) 有一堆木棍大约有n根,木棍的长度和重量都预先知道,这些木棍会在一个木工机械上一个接一个的处理,这需要一些时间,称为设置时间,为机械准备处理一根木头, ...
- Java 单元测试Junit
@Test @Before @After 测试方法运行前执行Before动作(比如创建资源),运行后执行After动作(比如销毁资源) @BeforeClass @AfterClass 测试类运行前执 ...
- 在安装twincat plc时,出现 there are some files marked for deletion on next reboot.please reboot first then
在注冊表内"HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\ "中删除注冊表值 " ...
- java 服务端解决ajax跨域问题
//过滤器方式 可以更改为拦截器方式public class SimpleCORSFilter implements Filter { public void doFilter(ServletRequ ...
- jq實現網頁個性title
<!DOCTYPE html> <html content="text/html; charset=UTF-8"> <title>tooltip ...
- Maven常用插件--转
=========Maven Report Plugin========= 1.源码分析 <artifactId>maven-pmd-plugin</artifactId> 2 ...
- linux服务器上的php代码通过nginx发布,解决pathinfo模式问题
附件1为修改前的正常访问php配置文件 附件2为修改后的能通过url地址访问php项目的配置文件 具体操作网址 如下:www.itokit.com/2012/0308/73275.ht ...