本文为廖雪峰Python教程的学习笔记
具体内容,可参考如下链接:
http://www.liaoxuefeng.com/
Python内置了很多函数,可以直接调用。Python内置的函数可以通过官方文档查看。也可以通过help()查看帮助信息。
函数名是指向函数对象的引用,把函数名赋给变量,相当于给函数起了别名。
# 变量a为函数abs()的别名
a = abs
a(-1) #结果为1
使用def 函数名(参数):语句定义函数,在缩进块中编写函数体,返回值用return语句返回,如果没有return语句,返回值为None,等价于return 。
根据需要,return语句也可以返回多个值组成的tuple,可以不写(),多个值之间用’,’隔开,调用函数时可以用多个变量接受返回值,多个变量按位置赋值。
#自定义取绝对值函数
def my_abs(x):
#isinstance()检查参数类型
if not isinstance(x, (int, float)):
raise TypeError('bad operand type')
if x >= 0:
return x
else:
return -x
将my_abs()保存在function.py文件中,在该目录下启动Python解释器,导入my_abs()函数,就可以调用函数。
>>> from function import my_abs
>>> print(my_abs(-1))
1
>>> print(my_abs(1))
1
pass语句可以用做占位符,表示什么都不做,可用来定义一个空函数。在没想好具体语句的时候,可以用pass语句使代码先运行起来。
#定义空函数
def nop():
pass
#放在if语句中
if a > b:
pass
将变化小的参数作为默认参数,如果没有传入或改变默认参数的值,则使用默认参数。如果不需要改变默认参数,不用传入默认参数;需要改变默认参数时,传入默认参数即可。
必选参数在前,默认参数在后。有多个默认参数时,调用的时候,既可以按顺序提供默认参数,也可以不按顺序提供部分默认参数。当不按顺序提供部分默认参数时,需要把参数名写上。表示该参数用传进去的值,其他默认参数继续使用默认值。
例如,学生注册信息,设置年龄和城市为默认参数
def enroll(name, gender, age = 7, city = 'Beijing'):
print('name = ', name, '\tgender = ', gender, '\tage = ', age, '\tcity = ', city)
enroll('Jim', 'M')
enroll('Lily', 'F', 6, 'Tianjin')
enroll('Tom', 'M', 8)
enroll('Jack', 'M', city = 'Xi\'an')
分别用四种方式调用enroll函数后,输出结果如下所示
name = Jim gender = M age = 7 city = Beijing
name = Lily gender = F age = 6 city = Tianjin
name = Tom gender = M age = 8 city = Beijing
name = Jack gender = M age = 7 city = Xi'an
默认参数必须指向不变对象。因为不变对象一旦创建,对象内部的数据就不能修改,这样就减少了由于修改数据导致的错误。此外,由于对象不变,多任务环境下同时读取对象不需要加锁,同时读一点问题都没有。在编写程序时,如果可以设计一个不变对象,那就尽量设计成不变对象。
def add_end(L = []):
L.append('end')
return L
#正常调用
print(add_end([1, 2, 3]))
print(add_end(['a', 'b', 'c']))
#使用默认参数调用
print(add_end())
print(add_end())
函数add_end()在正常调用时,输出结果为:
[1, 2, 3, 'end']
['a', 'b', 'c', 'end']
调用默认参数时,结果为:
['end']
['end', 'end']
Python函数在定义时,默认参数的值已经被计算出来。因为列表为可变对象,L指向可变对象,每次调用函数时,如果改变了L的内容,下次调用时,默认参数的内容就变了,不是函数定义时的列表了。函数add_end()可做如下修改,用不可变对象None实现:
def add_end(L = None):
if L is None:
L = []
L.append('end')
return L
#使用默认参数调用
print(add_end())
print(add_end())
再使用默认参数调用时,结果为:
['end']
['end']
传入的参数个数可变,可以为0到任意个。
在参数前加*实现可变参数。
可变参数在函数调用时自动组装为一个tuple。
在列表和元组前加*,可以将列表或元组中的元素变为可变参数传入函数。
def add_sum(*nums):
sum = 0
for num in nums:
sum += num
return sum
print(add_sum(1, 2, 3))
L = [1, 2, 3, 4]
print(add_sum(*L))
T = (1, 2)
print(add_sum(*T))
运行结果为:
6
10
3
将任意个含参数名的参数组装为一个dict。
在参数前加**实现关键字参数。
在dict前加**,可以将dict作为为关键字参数传入函数。传入的为dict的拷贝,在函数中的修改不会影响函数外的dict。
例如,函数person()包含必选关键字name和age,还包含关键字参数kw
def person(name, age, city = 'Beijing', country = 'china', **kw):
print('name: ', name, '\tage: ', age, '\tcity: ', city, '\tcountry: ', country, '\tother: ', kw)
#dict
other = {'gender': 'F', 'height': 168}
person('Tom', 18)
person('Lily', 20, city = 'Tianjin', gender = 'F', hobby = 'read')
person('Tim', 15, gender = 'M', city = 'Beijing')
#将dict作为关键字参数传入
person('Ann', 16, **other)
运行结果如下:
name: Tom age: 18 city: Beijing country: china other: {}
name: Lily age: 20 city: Tianjin country: china other: {'gender': 'F', 'hobby': 'read'}
name: Tim age: 15 city: Beijing country: china other: {'gender': 'M'}
name: Ann age: 16 city: Beijing country: china other: {'gender': 'F', 'height': 168}
关键字参数可以传入任意多个名字,对名字没有限制。
如果要限制关键字参数的名字,需要在参数列表中使用*,*之后的关键字为命名关键字,只接受这些参数作为关键字名字。
如果已经有可变参数,不需要特殊分隔符*
def person(name, age, *, city, country):
print('name: ', name, '\tage: ', age, '\tcity: ', city, '\tcountry: ', country)
#如果已经有可变参数,不需要特殊分隔符*
def person1(name, age, *args, city, country):
print('name: ', name, '\tage: ', age, '\tcity: ', city, '\tcountry: ', country)
调用函数时,必须传入参数名,位置可以颠倒。
person('Tom', 18, city = 'Tianjin',country = 'china')
person('Tom', 18, country = 'china', city = 'Tianjin')
person1('Tom', 18, city = 'Tianjin',country = 'china')
person1('Tom', 18, country = 'china', city = 'Tianjin')
该函数只接受两个位置参数,如果调用时不用函数名(person(‘Tom’, 18, ‘Tianjin’, ‘china’)), Python解释器认为传入了四个位置参数,会报错。
如果命名关键字参数有缺省值,调用时可以不传入该参数。
不同类型的函数可以组合使用,参数定义的顺序必须为:必选参数,默认参数,可变参数,命名关键字参数和关键字参数。
def func1(a, b, c = 0, *d, e, **kw):
print(a, '\t', b, '\t', c, '\t', d, '\t', e, '\t', kw)
def func2(a, b, c = 0, *, d, e, **kw):
print(a, '\t', b, '\t', c, '\t', d, '\t', e, '\t', kw)
def func3(a, b, c):
print(a, '\t', b, '\t', c)
t = (3, 4, 5, 6, 7, 8, 9)
l = [3, 4, 5, 6, 7, 8, 9]
t1 = (4, 5, 6)
dic = {'name': 'Z', 'gender': 'M'}
print('func1')
func1(1, 2, e = 4, d = 3)
func1(1, 2, d = 3, e = 4)
func1(1, 2, d = 3, e = 4, name = 'L', gender = 'F')
func1(*t, e = 10)
func1(*l, e = 10)
func1(*t, e = 11, **dic)
func1(*l, e = 11, **dic)
print('func2')
func2(1, 2, d = 3, e = 4)
func2(1, 2, d = 3, e = 4, name = 'L', gender = 'F')
func2(*t1, d = 20, e = 20)
func2(*t1, d = 21, e = 21, **dic)
func3(*t1)
输出为:
func1
1 2 0 () 4 {'d': 3}
1 2 0 () 4 {'d': 3}
1 2 0 () 4 {'name': 'L', 'gender': 'F', 'd': 3}
3 4 5 (6, 7, 8, 9) 10 {}
3 4 5 (6, 7, 8, 9) 10 {}
3 4 5 (6, 7, 8, 9) 11 {'name': 'Z', 'gender': 'M'}
3 4 5 (6, 7, 8, 9) 11 {'name': 'Z', 'gender': 'M'}
func2
1 2 0 3 4 {}
1 2 0 3 4 {'name': 'L', 'gender': 'F'}
4 5 6 20 20 {}
4 5 6 21 21 {'name': 'Z', 'gender': 'M'}
4 5 6
func1中,
d为可变参数,可以为空,d=3被认为是关键字参数;
e为命名关键字参数,调用时必须使用名字调用;
用*t, *l, *dic调用时,*t, *l的前三个元素作为必选参数a, b, 默认参数c,后面的部分作为命名关键字e = 10,剩下的部分作为可变参数构成tuple d = (6, 7, 8, 9), **dic作为关键字参数。
func2中,
d, e均为命名关键字,必须使用名字调用。
因为不包含可变参数,如果要使用tuple, list调用,tuple和list的长度必须不超过固定参数加默认参数的长度,所以只能使用t1进行调用。