大多数编程语言都绕不开一个名词,那就是--函数(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_函数参数及参数传递的更多相关文章

  1. python学习笔记:函数参数

    1. 位置参数:一般的参数 2. 默认参数: def power(x, n=2): s = 1 while n > 0: n = n - 1 s = s * x return s 参数里有默认赋 ...

  2. Python学习手册之 Python 之禅、Python 编程规范和函数参数

    在上一篇文章中,我们介绍了 Python 的正则表达式使用示例,现在我们介绍 Python 之禅. Python 编程规范和函数参数.查看上一篇文章请点击:https://www.cnblogs.co ...

  3. Python学习笔记7-把函数当参数传递、指定可变参数

    把函数当参数传递 # 函数参数传递 # 面向对象编程就是把对象传来传去 # 面向函数编程就是把函数传来传去 def mytest(num): return num * 2 # # 不光可以传递变量,还 ...

  4. python学习道路(day4note)(函数,形参实参位置参数匿名参数,匿名函数,高阶函数,镶嵌函数)

    1.函数 2种编程方法 关键词面向对象:华山派 --->> 类----->class面向过程:少林派 -->> 过程--->def 函数式编程:逍遥派 --> ...

  5. python学习笔记(3)--函数、参数、变量、递归

    1.函数基本语法和特性 背景摘要 现在老板让你写一个监控程序,监控服务器的系统状况,当cpu\memory\disk等指标的使用量超过阀值时即发邮件报警,你掏出了所有的知识量吗,写出了以下代码 whi ...

  6. Python 学习:常用函数整理

    整理Python中常用的函数 一,把字符串形式的list转换为list 使用ast模块中的literal_eval函数来实现,把字符串形式的list转换为Python的基础类型list from as ...

  7. 【Python学习之五】函数

    环境 虚拟机:VMware 10 Linux版本:CentOS-6.5-x86_64 客户端:Xshell4 FTP:Xftp4 python3.6 Python不但能非常灵活地定义函数,而且本身内置 ...

  8. python学习之---匿名函数,返回函数,偏函数

    1. 返回函数: 所谓的返回函数,指的是函数作为返回值.高阶函数除了可以接受函数作为参数外,同样可以接受函数作为结果返回.以下是一个可变参数的求和例子,一般求和函数是如此这般定义的: >> ...

  9. Python学习---高阶函数的学习

    高阶函数 高阶函数:函数名可以作为参数传递输入,函数名还可以作为返回值返回 函数名可以重新赋值,因为其本身就是一个变量    函数本身就是一个对象,    函数的变量名f本身就是指向函数本身的,加上括 ...

随机推荐

  1. Redis源码阅读笔记(1)——简单动态字符串sds实现原理

    首先,sds即simple dynamic string,redis实现这个的时候使用了一个技巧,并且C99将其收录为标准,即柔性数组成员(flexible array member),参考资料见这里 ...

  2. 【转】Ansys 13.0 flexlm not running完美解决方案

    http://jingyan.baidu.com/article/af9f5a2dd9843a43150a4550.html 实测,12.1 用此方法问题同样得解.

  3. SPBF(队列优化的Bellman-Foord)

  4. 一个js变量以及其作用域的源码示例

    今天遇到了一个问题,抽象出来的代码如下: var zoom=13; function setZoom(){ zoom=14; } function displayZoom(){ this.setZoo ...

  5. Codeforces 544E Remembering Strings 状压dp

    题目链接 题意: 给定n个长度均为m的字符串 以下n行给出字符串 以下n*m的矩阵表示把相应的字母改动成其它字母的花费. 问: 对于一个字符串,若它是easy to remembering 当 它存在 ...

  6. MyBatis报错

    1.错误描写叙述 2014-11-2 15:03:11 org.apache.catalina.core.StandardEngine start 信息: Starting Servlet Engin ...

  7. Bigcommerce:intershop编程经验总结

    1.修改或者添加网页Title,Keywords,Decoration的代码: $full_url = $_SERVER['REQUEST_URI'];  //获取请求的url $letter = s ...

  8. Meth | phpstorm invalid descendent file name

     Failed to collect files: Invalid descendent file name "codelog_ddz.\"(]))\",\').txt& ...

  9. Java 7之多线程- Semaphore--转载

    Semaphore用于保存当前可用许可的数量.是通过共享锁实现的.根据共享锁的获取原则,Semaphore分为"公平信号量"和"非公平信号量". "公 ...

  10. java mysql驱动

    mysql驱动方式有三种, 1.第一种是先把jar包放在项目的目录下,通过添加jar包,是使用相对地址的,这样把项目复制到其它电脑也可以用 2.第二种方法是导入外部的jar包,是绝对地址,如果项目要复 ...