位置参数

def power(x):
return x*x;

默认参数

指的是在函数定义的时候,就赋予一些参数默认值,在调用这个函数的时候不必多次传入重复的参数值。

如定义一个多次输出同一个年龄阶段和同一个城市的学生的姓名和性别。

def info(name,gender,age=20,city='sichuan'):
print('name:', name)
print('gender:', gender)
print('age',age)
print('city',city)
info("xiaoqian","nv")
info("xiangj",'nan')

从上面可以看出,默认参数可以简化函数的调用,设置默认参数时,有几点要注意:

一是必选参数在前,默认参数在后。

二是如何设置默认参数。

但是默认参数虽然好,但是也有坑:就是在定义默认参数的时候,默认参数必须是不可变对象。

可变参数(*)

可变参数就是传入的参数个数是可变的,可以是1个,2个或多个,甚至是0个

def calc(*numbers):
sum = 0;
for n in numbers:
sum = sum + n;
return sum;
calc();
calc(1,2,3);

如果有一个list或者是tuple,要调用一个可变参数怎么办?

python允许在list或者tuple前面加上*,传给函数。

num  = [1,2,3];
cal(*num);

可变参数允许传入0,1,n个参数,在调用的时候会自动将这些参数组装成一个tuple。而关键字参数允许你传入0个或人一个含参数名的参数,这些关键字参数在函数内部自动组装成一个dict。

关键字参数(**)

def person(name,age,**kw):
print('name',name,'age',age,'other',kw) person('tom',20);
person('tom1',10,city="beijinh");
person('tom2',30,gender="m",city="beijing");

也可以将上面的gender和city参数组装成一个dict后,再传给函数

extra = {'city':'beijing','job':'engin'};
person('tom11',100,city=extra['city'],job=extra['job']);
person("tom11",100,**extra);
//注意这里kw获得的是extra的一份拷贝,对kw的改动不会影响到函数外的extra

命名关键字参数(*特殊分隔符)

关键字参数的调用,函数可以接受不受限制的关键字参数。

但是有时候也需要限制关键字参数个数,所以这时候就需要用到命名关键字参数

def person(name,age,*,city,job):
print(name,age,city,job);
//命名关键字参数需要一个特殊分隔符*,*后面的参数被视为命名关键字参数。 person("jackl",14,city="beijing",job="gee");
//命名关键字参数必须传入参数名,这和位置参数不同,如果没有传入参数名,调用就将报错

如果函数定义中已经有了一个可变参数,后面跟着的命名关键字参数就不需要*这个特殊分隔符了。

def person(name,age,*args,city,job):
print(name,age,args,city,job)

要特别注意:如果没有可变参数,必须加一个作为特殊分隔符,否则Python将无法识别位置参数和命名关键字参数。

总结:

python函数一共有5种参数:必选参数,默认参数,可变参数,关键字参数,命名关键字参数。可以将这几个参数组合使用。但是要注意:参数定义的顺序必须是:

必选参数,默认参数,可变参数,命名关键字参数和关键字参数。

默认参数一定要用不可变对象

args是可变参数,args接受的是一个tuple。

**kw是关键字参数,kw接受的是一个dict。

可变参数可以直接传入:func(1,2,3),又可以组装list或者tuple,再通过
args传入:func(
(1,2,3))

关键字参数既可以直接传入func(a=1,b=2),又可以先组装dict,然后通过kw传入func({'a':1,'b':2})

命名关键字参数是为了限制调用者可以传入的参数名,同时可以提供默认值。

定义命名的关键字出纳号苏时,在没有可变参数的情况下,不要忘了写特殊分隔符*,否则定义的将是位置参数。

递归函数

递归函数的优点是定义简单,逻辑清晰。但是有时候会出现栈溢出。

解决栈溢出的方法是尾递归。事实上,尾递归和循环的效果是一样的,把循环看成一种特殊的尾递归函数也是可以的

尾递归:在函数返回的时候,调用自身本身,并且,return语句不能包含表达式。

def fact(n):
if n == 1:
return 1
return n * fact(n-1)

上面的return中包含了表达式,这种不是尾递归。

def fact_item(num,product):
if num == 1:
return product
return fact_item(num-1,num*product)

上面这种是尾递归,做了优化,栈不会增长,因此多少次调用也不会导致栈溢出。

遗憾的是,大多数编程语言没有针对尾递归做优化,Python解释器也没有做优化,所以,即使把上面的fact(n)函数改成尾递归方式,也会导致栈溢出

Python的函数参数和递归参数的更多相关文章

  1. python的函数介绍 位置参数 关键字参数 默认参数 参数组 *args **kwargs

    1.数学意义的函数与python中的函数 数学意义的函数 y = 2*3+1 x =3 y =7 x是自变量,y是因变量 2.python中定义函数的方法 一个函数往往都是为了完成一个特定的功能而存在 ...

  2. python中函数的不定长参数

    例1: #定义一个含有不定长参数的函数,本例第三个参数*args def sum_nums(a,b,*args): print('_'*30) print(a) print(b) print(args ...

  3. python学习笔记12(函数三): 参数类型、递归、lambda函数

    一.函数参数的类型 之前我们接触到的那种函数参数定义和传递方式叫做位置参数,即参数是通过位置进行匹配的,从左到右,依次进行匹配,这个对参数的位置和个数都有严格的要求.而在Python中还有一种是通过参 ...

  4. Python学习5——抽象,涉及抽象和结构、函数的自定义、参数、作用域、递归

    此处将抽象和结构.自定义函数.参数的使用.作用域.递归放在一起学习,看起来很怪是不是? 但实际上这几者之间是有紧密联系的,不然Python基础教程(第三版)的作者为什么会把它们放在一起哪?手动滑稽 好 ...

  5. python学习7—函数定义、参数、递归、作用域、匿名函数以及函数式编程

    python学习7—函数定义.参数.递归.作用域.匿名函数以及函数式编程 1. 函数定义 def test(x) # discription y = 2 * x return y 返回一个值,则返回原 ...

  6. python之函数、参数、作用域、递归

    函数的定义 函数也就是带名字的代码块.使用关键字def来定义,指出函数名及参数,以冒号结尾. def fibs(num): result =[0,1] for i in range(num-2): r ...

  7. Python基础(函数,函数的定义,函数的调用,函数的参数,递归函数)

    1.函数 我们知道圆的面积计算公式为: S = πr2 当我们知道半径r的值时,就可以根据公式计算出面积.假设我们需要计算3个不同大小的圆的面积: r1 = 12.34 r2 = 9.08 r3 = ...

  8. python中函数的参数和返回值

    目录 函数 目标 01. 函数参数和返回值的作用 1.1 无参数,无返回值 1.2 无参数,有返回值 1.3 有参数,无返回值 1.4 有参数,有返回值 02. 函数的返回值 进阶 示例 -- 温度和 ...

  9. Python——函数的命名关键字参数

    命名关键字参数 对于关键字参数,函数的调用者可以传入任意不受限制的关键字参数.至于到底传入了哪些,就需要在函数内部通过kw检查. 仍以person()函数为例,我们希望检查是否有city和job参数: ...

随机推荐

  1. ms17010利用失败解决一则

    没有反弹得到session并且提示如下: [-] 10.0.131.2:445 - Service failed to start, ERROR_CODE: 216 换了一个payload set p ...

  2. frp 使用入门

    1.下载安装对应系统版本 https://github.com/fatedier/frp/releases/ 2.将下载的frp移动到系统软件目录 mv frp/ /usr/local 3.配置frp ...

  3. linux中字符串转换函数 simple_strtoul【转】

    转自:http://blog.csdn.net/tommy_wxie/article/details/7480087 Linux内核中提供的一些字符串转换函数: lib/vsprintf.c [htm ...

  4. 002 Lock和synchronized的区别和使用

    转自 https://www.cnblogs.com/baizhanshi/p/6419268.html 今天看了并发实践这本书的ReentantLock这章,感觉对ReentantLock还是不够熟 ...

  5. swift中闭包的循环引用

    首先我们先创造一个循环引用 var nameB:(()->())? override func viewDidLoad() { super.viewDidLoad() let bu = UIBu ...

  6. python笔记_查看函数调用栈的一个小技巧

    一.背景 最近在看一个开源框架的源码,涉及到的内容非常杂乱,有的函数不知道是在什么时候被谁给调用了?调用的时候传入了什么参数?为了解决这个问题,写了一个小的装饰器. 二.实现 这个装饰器函数主要参考了 ...

  7. 12:django 模板 内建过滤器

    django 模板 内建过滤器 add{{ value|add:"2" }} 对象的加法,如果都是整数类型,简单的算术加法:如果是列表,则是列表的相加 如果无法执行对象的相加,比如 ...

  8. RSA的公钥和私钥到底哪个才是用来加密和哪个用来解密?

    https://www.zhihu.com/question/25912483?sort=created

  9. Cloudstack平台实战

    https://blog.csdn.net/zhangliu463884153/article/details/80606020

  10. MITx 创业101 寻找你的顾客

    来自MITx的创业课 步骤一 市场分割(Market Segmentation) 头脑风暴所有可能的市场,关注可能性 寻找最终用户(End User)——会使用你的产品的用户,但不一定会付钱 思考产品 ...