【廖雪峰Python教程】二、函数

参考资料 Python教程 - 廖雪峰的官方网站 (liaoxuefeng.com)

二、函数

  1. 定义函数
  • 缩进块中编写函数体,函数的返回值用return语句返回。 函数遇到 return 语句时,它会立即结束并返回相应的值,不再执行后续的代码,这在写判断语句时关于循环内还是循环外尤其要注意。

  • pass可以用来作为占位符,比如现在还没想好怎么写函数的代码,就可以先放一个pass,让代码能运行起来

    •   def nop():
            pass
        
        if age >= 18:
            pass
      
  • 小结

    • 定义函数时,需要确定函数名和参数个数;

    • 如果有必要,可以先对参数的数据类型做检查;

    • 函数体内部可以用return随时返回函数结果;

    • 函数执行完毕也没有return语句时,自动return None

    • 函数可以同时返回多个值,但其实就是一个tuple。

  1. 函数的参数
  • 位置参数

    • power(x, n)函数有两个参数:x和n,这两个参数都是位置参数,调用函数时,传入的两个值按照位置顺序依次赋给参数x和n
  • 默认参数

    • 可以简化函数的调用

    • 由于我们经常计算x2,所以,完全可以把第二个参数n的默认值设定为2。

      • 这样,当我们调用power(5)时,相当于调用power(5, 2),而对于n > 2的其他情况,就必须明确地传入n,比如power(5, 3)
    • 设置时注意

      • 一是必选参数在前,默认参数在后,否则Python的解释器会报错(思考一下为什么默认参数不能放在必选参数前面);
      • 二是如何设置默认参数。
        • 当函数有多个参数时,把变化大的参数放前面,变化小的参数放后面。变化小的参数就可以作为默认参数。
    • ❗定义默认参数要牢记一点:默认参数必须指向不变对象❗

    • 	def add_end(L=None):  # 不能直接def add_end(L=[]):,此时的列表是可变的
      	    if L is None:
      	        L = []
      	    L.append('END')
      	    return L
      	```
      
      
  • 可变参数:*args

    • *nums表示把nums这个list的所有元素作为可变参数传进去。
    • 可变参数允许你传入0个或任意个参数,这些可变参数在函数调用时自动组装为一个tuple
  • 关键字参数:**kw【key words】

    • 允许你传入0个或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个dict

    • 作用:扩展函数的功能。

    • 用法:不是必选参数,函数的调用者可以传入任意不受限制的关键字参数,可以用来填入多个其他类别名和对应内容

      •   def person(name, age, **kw):
              print('name:', name, 'age:', age, 'other:', kw)
          
           >>> person('Adam', 45, gender='M', job='Engineer')
          name: Adam age: 45 other: {'gender': 'M', 'job': 'Engineer'}   
        
    • **extra表示把extra这个dict的所有key-value用关键字参数传入到函数的**kw参数,kw将获得一个dict,注意kw获得的dict是extra的一份拷贝,对kw的改动不会影响到函数外的extra

  • 命名关键字参数: *, city, job

    • 限制关键字参数的名字,就可以用固定的命名关键字参数,例如,只接收cityjob作为关键字参数

      •   def person(name, age, *, city, job):
              print(name, age, city, job)
              
          >>> person('Jack', 24, city='Beijing', job='Engineer') #命名关键词参数必须写上参数名
        
    • 如果函数定义中已经有了一个可变参数,后面跟着的命名关键字参数就不再需要一个特殊分隔符*了.直接依次写后面

  • 参数组合

    • 参数定义的顺序必须是:必选参数、默认参数、可变参数、命名关键字参数和关键字参数
    • 通过一个tuple和dict,也可以调用相关函数
      • args = (1, 2, 3, 4)会依次将数字给入必选参数到默认参数等
      • kw = {‘d’: 99, ‘x’: ‘#’}则会依次给入命名关键词参数和关键词参数,以其各自固定的键值对/字典格式
    • 对于任意函数,都可以通过类似func(*args, **kw)的形式调用它,无论它的参数是如何定义的。
  • 小结

    • 默认参数一定要用不可变对象,如果是可变对象,程序运行时会有逻辑错误!

    • 要注意定义可变参数和关键字参数的语法:

      • *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})
    • 使用*args**kw是Python的习惯写法。

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

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

  1. 递归函数
  • 判别:如果一个函数在内部调用自身本身,这个函数就是递归函数。

  • 注意:

    • 防止栈溢出
      • 函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出。
      • 解决方法:尾递归优化
        • 函数返回的时候,调用自身本身,并且,return语句不能包含表达式
        • 使递归本身无论调用多少次,都只占用一个栈帧,不会出现栈溢出的情况。
      • 针对尾递归优化的语言可以通过尾递归防止栈溢出。尾递归事实上和循环是等价的,没有循环语句的编程语言只能通过尾递归实现循环。
      • Python标准的解释器没有针对尾递归做优化,任何递归函数都存在栈溢出的问题。
  • 写递归算法tips:

    • 不要过于关注展开思考的它的中间过程,❗想清楚n是n-1通过什么逻辑得到的即可❗。
  • 16
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值