Python函数

Python不但能非常灵活地定义函数,而且本身内置了很多有用的函数,可以直接调用。

一、定义函数

在Python中,定义一个函数要使用def语句,依次写出函数名、括号、括号中的参数和冒号:,然后,在缩进块中编写函数体,函数的返回值用return语句返回。

  def my_abs(x):
        if x >= 0:
              return x
        else:
              return -x

二、导入外部函数

  from 外部文件名 import 外部函数名

三、空函数

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

  def nop():
        pass

缺少了pass,代码运行就会有语法错误。

  if age >= 18:
        pass

四、求绝对值的abs函数

  abs(100)

五、求最大值的函数max

max()可以接收任意多个参数,并返回最大的那个

  max(2, 3, 1, -5)

六、数据类型转换函数

比如int()函数可以把其他数据类型转换为整数

  int('123')
  float('12.34')
  str(1.23)
  bool(1)

七、把一个整数转换成十六进制表示的字符串

  hex()

八、给函数起别名

函数名其实就是指向一个函数对象的引用,完全可以把函数名赋给一个变量,相当于给这个函数起了一个“别名”。

  a = abs # 变量a指向abs函数
  a(-1) # 所以也可以通过a调用abs函数

九、数据类型检查函数

  isinstance()

十、函数返回“多个值”

其实这只是一种假象,Python函数返回的仍然是单一值
返回值是一个tuple!但是,在语法上,返回一个tuple可以省略括号,而多个变量可以同时接收一个tuple,按位置赋给对应的值,所以,Python的函数返回多值其实就是返回一个tuple,但写起来更方便。

十一、函数参数

(1)位置参数

  def power(x):
  return x * x

对于power(x)函数,参数x就是一个位置参数。

(2)默认参数

  def power(x, n=2):
        s = 1
        while n > 0:
              n = n - 1
              s = s * x
              return s

这里的n=2就是默认参数

默认参数的注意事项
(Ⅰ)必选参数在前,默认参数在后,否则Python的解释器会报错;
(Ⅱ)当函数有多个参数时,把变化大的参数放前面,变化小的参数放后面。变化小的参数就可以作为默认参数;
(Ⅲ)当不按顺序提供部分默认参数时,需要把参数名写上;
(Ⅳ)定义默认参数要牢记一点:默认参数必须指向不变对象!

(3)可变参数

可变参数就是传入的参数个数是可变的,可以是1个、2个到任意个,还可以是0个。
在参数前面加一个*号,就可以定义可变参数

  def calc(*numbers):
        sum = 0
        for n in numbers:
              sum = sum + n * n
              return sum

特别的,如果已经有一个list或者tuple,要调用一个可变参数怎么办?

  nums = [1, 2, 3]
  calc(*nums)

*nums表示把nums这个list的所有元素作为可变参数传进去。这种写法相当有用,而且很常见。

(4)关键字参数

**参数名

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

def person(name, age, **kw):
print('name:', name, 'age:', age, 'other:', kw)

传入dict:**dict名

(5)命名关键字函数

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

和关键字参数**kw不同,命名关键字参数需要一个特殊分隔符后面的参数被视为命名关键字参数。

如果函数定义中已经有了一个可变参数,后面跟着的命名关键字参数就不再需要一个特殊分隔符*了:
def person(name, age, *args, city, job):
print(name, age, args, city, job)

命名关键字参数可以有缺省值,从而简化调用:

  def person(name, age, *, city='Beijing', job):
        print(name, age, city, job)

(6)参数组合
在Python中定义函数,可以用必选参数、默认参数、可变参数、关键字参数和命名关键字参数,这5种参数都可以组合使用。但是请注意,参数定义的顺序必须是:必选参数、默认参数、可变参数、命名关键字参数和关键字参数。

def f1(a, b, c=0, *args, **kw):
print('a =', a, 'b =', b, 'c =', c, 'args =', args, 'kw =', kw)

def f2(a, b, c=0, *, d, **kw):
print('a =', a, 'b =', b, 'c =', c, 'd =', d, 'kw =', kw)

(7)对于任意函数,都可以通过类似func(*args, **kw)的形式调用它,无论它的参数是如何定义的。

十二、递归函数

在函数内部,可以调用其他函数。如果一个函数在内部调用自身本身,这个函数就是递归函数。

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

使用递归函数需要注意防止栈溢出。

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

尾递归是指,在函数返回的时候,调用自身本身,并且,return语句不能包含表达式。这样,编译器或者解释器就可以把尾递归做优化,使递归本身无论调用多少次,都只占用一个栈帧,不会出现栈溢出的情况。

  def fact(n):
        return fact_iter(n, 1)

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

尾递归调用时,如果做了优化,栈不会增长,因此,无论多少次调用也不会导致栈溢出。

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

十三、总结

(1)定义可变参数和关键字参数的语法:

*args是可变参数,args接收的是一个tuple;
**kw是关键字参数,kw接收的是一个dict。

(2)调用函数时如何传入可变参数和关键字参数的语法:

可变参数既可以直接传入:func(1, 2, 3),又可以先组装list或tuple,再通过args传入:func((1, 2, 3));
关键字参数既可以直接传入:func(a=1, b=2),又可以先组装dict,再通过kw传入:func({'a': 1, 'b': 2})。

博客内容用于记录自己学习后的收获,如有侵权请联系我删除
原文地址:https://www.cnblogs.com/ptxiaochen/p/13621033.html