python中函数的定义使用 def
语句,依次写函数名,括号,参数, 冒号 :
,然后缩进语句块,有返回值的使用return语句,如果没有返回值的,可以写'return',或者'return None'
def my_fun(x):
if x >=0:
return x
else:
return -x
一.空函数
python中使用 pass
语句
def none_fun:
pass
这样有些代码如果没有想好就可以先跳过,当然 pass 语句还可以用于其它语句中
if x >= 100:
pass
二.函数参数
1.默认参数
python的默认参数和C#中的默认参数很类似,一般将变化小的参数写在后面,可以提供有名实参而不用考虑参数的顺序等
def enroll(name, gender, age=6, city='wuhan'):
print('name:', name)
print('gender:', gender)
print('age:', age)
print('city:', city)
enroll('james', 'F')
enroll('kobe', 'M', city='Los Angle')
值得注意的是:默认参数必须指向不变对象
如果指向的是可变对象,比如list类型,则可能出现意想不到的结果
def add_end(L=[]):
L.append('END')
return L
>>> add_end()
['END']
>>> add_end()
['END', 'END']
这是因为python函数在定义时,默认参数L的值被计算出来了,即[],因为L也是一个变量,指向对象[],每次调用该函数,如果改变L的内容,下次调用时,默认参数的内容就改变了
可以改为:
# 将默认参数指向一个不可变对象None
def add_end(L=None):
if L is None:
L = []
L.append('END')
return L
>>> add_end()
['END']
>>> add_end()
['END']
使用 is 关键词,这关键词和js中一致
2.可变参数*
其实就是js中的spread操作符,python中使用 *
表示, 可变参数在函数调用时实际上自动组装成一个元组tuple
def calc(*numbers):
sum = 0
for n in numbers:
sum += n * n
return sum
# 对于一般的数,可以直接传入
calc(1, 2)
calc(1, 2, 3)
# 对于list tuple等集合元素,可以像js中先展开
# list [1, 2, 3]
L = [1, 2, 3]
calc(*L)
T = (1, 2, 3)
calc(*T)
3.关键字参数 **
关键字参数允许传入0个或任意个含参数名的参数,这些关键字参数在函数内部自动组装成一个 dict, 表示方式为 **
示例:
def person(name, age, **kw):
print('name:', name, 'age:', age, 'other:', kw)
# 关键字参数自动组装成字典dict
>>> person('james', 28, city='wuhan', hobby='base')
name: james, age: 28, other: {city: 'wuhan', hobby='base'}
# 可以直接传入一个字典dict, 但是需要在字典前保留 '**'
>>> info = {gender: 'M', hobby: 'basketball'}
>>> person('james', 28, **info)
name: james, age: 28, other: {gender: 'M', hobby: 'basketball'}
值得注意的是,传入到函数中的info字典只是外部定义的info的拷贝,函数中的info改变不会影响到外部的info字典
4.命名关键字参数
用于限制关键字参数的名字,比如说,下面的'city', 'job', 如果2个关键字参数少一个都会报错,同时也可以提供默认值,使用方式有几种
1.在命名关键字参数前添加一个*作为特殊参数分割符
def person(name, age, *, city, job):
print(name, age, city, job)
>>> person('Louis', 28, city='Beijing')
> TypeError: person() missing 1 required keyword-only argument: 'job'
2.如果使用了可变参数,则可变参数后面的参数为命名关键字参数
# 可变参数*args后面的 city, job为命名关键字参数
def person(name, age, *args, city, job)
print(name, age, args, city, job)
>>> person('james', 19, 'beijng', city='wuhan', job='worker')
james 19 ('beijng',) wuhan worker
# 缺少命名关键字参数则会报错
>>> person('james', 19, 'beijng')
TypeError: person() missing 2 required keyword-only arguments: 'city' and 'job'
参数组合
python中定义函数,可以使用必选参数,默认参数,可变参数,关键字参数,命名关键字参数,但是要注意这5种参数的顺序是:可变参数,默认参数,可变参数,命名关键字参数, 关键字参数
示例:
# a,b必选参数, c默认参数,*args可变参数, **kw 关键字参数
def f1(a, b, c=0, *args, **kw):
print('a =', a, 'b =', b, 'c =', c, 'args =', args, 'kw =', kw)
# a,b必选参数, c默认参数,d命名关键字参数, **kw 关键字参数
def f2(a, b, c=0, *, d, **kw):
print('a =', a, 'b =', b, 'c =', c, 'd =', d, 'kw =', kw)
# 使用fun(*args, **kw)的形式
>>> args = (1, 2, 3, 4)
>>> kw = {'d': 99, 'x': '#'}
>>> f1(*args, **kw)
a = 1 b = 2 c = 3 args = (4,) kw = {'d': 99, 'x': '#'}
>>> args = (1, 2, 3)
>>> kw = {'d': 88, 'x': '#'}
>>> f2(*args, **kw)
a = 1 b = 2, c = 3 d = 88 kw = {'x': '#'}
*对于任意函数,都可以通过类似func(args, kw)的形式去调用它
三.引入模块
这一点和js中的import很像,假如当前路径下有个文件名叫 'hello.py', 这个文件里面有个函数叫 'my_abs',可以在其它模块中引用这个函数
from hello import my_abs
引入语言自带的一些库函数可以直接使用improt
import math
另外在terminal中可以使用下列命令查看文件的内容
more hello.py
四.返回多个值
这个其实是语法糖,本质上返回的是 tuple 数据类型,省略括号之后就看起来像返回多个值
import math
def move(x, y, step, angle=0):
nx = x + step * math.cos(angle)
ny = y + step * math.sin(angle)
return nx, ny
>>> x, y = move(100, 100, 60, math.pi / 6)
>>> print(x, y)
151.96152422706632, 70.0
# 可以写为
>>> t = move(100, 100, 60, math.pi / 6)
>>> print(t)
(151.96152422706632, 70.0)
# 可以看出返回的实际上是一个tuple
五.递归函数
递归函数就是函数自调用,使用尾部调用的方式可以优化递归调用,这点和其它语言一样。
尾部调用就是函数返回的时候,调用自身本身,并且return语句不能包含表达式
# 没有进行尾部调用优化
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)
六.参数检查 raise
可以使用 raise 语句返回错误类型,相当于js中的throw,抛出错误
def my_abs:
if not isinstance(x, (int, float)):
raise TypeError('bad operand type')
if x >= 0:
return x
else:
return -x
另外可以看到:
- isinstance: 这个用于判断数据类型,和js中的instanceOf类似
总结
本章主要介绍python中的函数,函数的定义形式,函数参数的几种类型,以及其它的一些知识:
- 使用
def
来定义函数 -
pass
语句,raise
语句(相当于js中的throw,抛出错误),is
关键词,isinstance()
方法(用于检查对象类型) - 函数参数类型:必选参数,默认参数,任意参数,命名关键字参数, 关键字参数
-
import
引入模块,from xxx import some_fun
引入某个文件中的某个函数模块
总的来说,python中的函数参数定义和其它语言差别不是很大,最主要的不同在于命名关键字参数,关键字参数
2017年3月4日 17:31:46