07-函数

  概述:本文主要分析Python中的函数


一、定义函数

语法格式

1 def funcName(params):
2     code block

  函数的返回值通过 return 语句返回。如果没有 return 语句,函数执行完毕后也会返回结果,只是结果为 None。return None 和 return 是相同的。

空函数

  如果函数还没想好怎么写,可以将函数体写作 pass,这是一个占位符,以便代码可以先运行起来。

参数检查

  Python 解释器能检查出函数参数个数不对的问题,并抛出 TypeError。但是 Python 解释器不能检查参数类型,这需要我们自己写入检查机制。

  数据类型检查可以用内置函数 isinstance() 实现:

1 def my_abs(x):
2     if not isinstance(x, (int, float)):
3         raise TypeError('bad operand type')
4     if x >= 0:
5         return x
6     else:
7         return -x

返回多个值

  Python 中可以使用 return 语句返回多个值,例如: return x, y 。接受返回值时,也用两个变量分别接收: a, b = move()

  但实际上,Python 是将多个值放在一个 tuple 中再返回,所以返回的还是一个值。从语法上来说,返回一个 tuple 可以省略括号,多个变量也可以同时接收一个 tuple。

 

二、调用函数

  我们只要知道函数的名称和参数,即可调用函数。如果不清楚函数的具体用法,可以在交互命令行通过 help(func) 来查看信息。

  调用函数的时候,如果传入的参数数量不对,则会报 TypeError 的错误,并给出错误信息。

数据类型转换

1 int(param)     # 将其他数据类型转换为 int
2 float(param)  # 将其他数据类型转换为 float
3 str(param)     # 将其他数据类型转换为 str
4 bool(param)   # 将其他数据类型转换为 bool
5 hex()             # 将整数转换为十六进制的字符串

 

三、函数的参数

位置参数

  函数定义时定义的参数,就是位置参数。调用函数时,传入的值按照位置顺序依次赋给参数。譬如 power(x, n) 中,x 和 n 就是位置参数。

默认参数

  我们在函数定义时,可以给参数指定一个默认值。如果调用时没有传入此参数的值,这个参数就会使用默认值,而不会抛出 TypeError。

  默认参数可以简化函数的调用,但是需要注意以下两点:

    • 必选参数在前,默认参数在后,否则会报错(如果默认参数在前面,如何确定传进来的参数是给默认参数的,还是给位置参数的?)
    • 如何设置默认参数(通常把经常变化的参数放在前面,作为普通的位置参数。很少需要变化的参数放在后面,作为默认参数)

  默认参数降低了调用函数的难度:对于很少变化的参数而言,我们在调用时不用对它传参,使用默认参数即可。只有少数的情况需要修改,此时再给默认参数传入新数据。

  有多个默认参数时,有两种传参的方式:

    • 按函数定义的顺序,提供默认参数(如果传入的参数个数不够,后面的仍用默认值)
    • 不按函数定义的顺序,提供默认参数(此时要把参数名写上,以确定这个数据是给哪个参数的)。譬如:enroll('Adam', 'M', city='Tianjin')

  默认参数必须指向不变对象,否则会引起错误。因为默认参数本身是个变量,如果我们改变了它的内容,下次调用时,默认参数的内容就变了:

def add_end(L=[]):
    L.append('END') # L的内容改变了
    return L

  我们可以令 L = None,指向不变的对象,这样就没有问题了。

可变参数

  所谓可变参数,就是指传入的参数个数是可变的。可变参数定义时,要在前面加上 *,如: def calc(*numbers)。在函数内部,参数 numbers 收到的是一个 tuple。

  如果我们已经有了一个 list 或 tuple,就不用一个一个传参了。我们可以直接在前面加一个 *,把 list 或 tuple 变成可变参数传进去:

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

关键字参数

  关键字参数允许我们传入 0 个或人一个含参数名的参数,这些关键字参数在函数内部自动组装成一个 dict。在定义函数时,关键字参数前要加 **。

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

  在调用时,可以只传入必选参数,也可以传入任意个关键字参数:

1 person('Bob', 35, city='Beijing')
2 person('Adam', 45, gender='M', job='Engineer')

  我们也可以先组装出一个 dict,然后把它转换为关键字参数传进去:

1 extra = {'city': 'Beijing', 'job': 'Engineer'}
2 person('Jack', 24, **extra)

  **extra 表示把 extra 这个 dict 的所有 key-value 用关键字参数传入到函数的 **kw 参数,kw 将获得一个 dict。注意:kw 获得的 dict 是 extra 的一份拷贝,对 kw 的改动不会影响到函数外的 extra。

命名关键字参数

  关键字参数到底传入到哪里?这需要在函数内部通过 kw 检查。例如检查是否有 city 和 job 参数:

1 def person(name, age, **kw):
2     if 'city' in kw:
3         pass
4     if 'job' in kw:
5         pass
6     print('name: ', name, 'age: ', age, 'other: ', kw)

  但是调用者还是可以不受限制地传入参数,如果要限制关键字参数的名字,就可以用命名关键字参数。命名关键字参数需要一个特殊分隔符 *,* 后面的参数都被视作命名关键字参数。例如,只接受 city 和 job 作为关键字参数:

1 def person(name, age, *, city, job):
2     pass

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

1 def person(name, age, *args, city, job):
2     pass

  命名关键字参数必须传入参数名,否则会报错。

  命名关键字参数可以有缺省值,调用时可以不传入具有缺省值的参数,从而简化调用:

1 def person(name, age, *, city='Beijing', job):
2     pass

参数组合

  Python 中的函数可以组合使用必选参数、默认参数、可变参数、关键字参数和命名关键字参数,但必须按上述顺序定义。我们也可以将参数写入 tuple 和 dict,然后调用上述函数:

1 def f1(a, b, c=0, *args, **kw):
2     print('a =', a, 'b =', b, 'c =', c, 'args =', args, 'kw =', kw)
3 
4 args = (1, 2, 3, 4)
5 kw = {'d': 99, 'x': '#'}
6 f1(*args, **kw)

 

posted @ 2019-10-25 09:44  Albert-陌尘  阅读(168)  评论(0编辑  收藏  举报