函数在编程语言中,常用来封装一小段代码,以完成某个特定的功能。而对于一些经常需要用到的功能代码,使用函数封装起来还能解决代码重复的问题,方便管理和维护。Python 函数对此有比较完善的支持。
函数定义和命名
Python 使用 def
关键词定义一个函数:
def say_hello():
print('hello, world.')
def
关键词后的 hello
是可以自定义函数名称,一般根据函数代码的功能用途来自己命名。可以使用任意字母,数字或下滑线组合成的字符串来命名。不过要注意,不能以数字开头。
另外,函数取名时要注意不能和系统函数重名。如果和系统函数使用了同样的名称,相当于是覆盖了系统函数,这将会导致一些难以排查的功能异常。那么如何确定自已想要使用的函数名称是否为系统已经使用了的函数名呢?
很简单,直接通过 print
函数来检查:
>>> print(len)
<built-in function len>
对于已经存在的函数名,会直接返回如上内置函数的提示。来试试不存在的函数名:
>>> print(len1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'len1' is not defined. Did you mean: 'len'?
可以看到会返回一段错误消息,提示函数没有定义。这就意味着可以放心的使用这个名称了。
开头已经定义好了一个以 say_hello
命名的函数,那么如何使用自定义的函数呢?答案是直接通过函数名来执行:
say_hello()
文档字符串
紧挨这函数名的下一行代码如果是一段字符串,会被识别为函数文档:
def say_hello():
'''跟世界打招呼'''
print('hello, world.')
函数文档字符串类似于给函数的一段文字注解,方便自己或其他人在不阅读代码的前提下快速了解函数的作用和功能。
函数文档字符串可以通过 __doc__
属性来获取到:
>>> print(say_hello.__doc__)
跟世界打招呼
函数传参
函数名后的括号用来定义传参,稍微改造一下上面的 say_hello
函数:
def say_hello(message):
print(f'hello, {message}')
通过添加的传参,这个函数可以在调用时根据需要定义不同的消息:
>>> say_hello('world')
hello, world
>>> say_hello('python')
hello, python
函数参数的数量可以根据需要任意定义:
def say_hello(message, append_message):
print(f'hello, {message}')
print(f'hello, {append_message}')
还可以根据需要设置默认值:
def say_hello(message, append_message=None):
print(f'hello, {message}')
if append_message:
print(f'hello, {append_message}')
有默认值的参数类似于一个非必填项,可以简化函数的使用。不过需要注意一点:函数默认值尽量不要使用列表,字典或类实例这种可变对象类型。因为函数默认值只计算一次,使用可变的数据类型可能会导致数据累积。轻则导致结果异常,重则产生内存泄漏问题。
位置参数和关键词参数
调用 Python 函数时,提供参数的方式可以概括为两类:位置参数和关键词参数。位置参数顾名思义,必须按函数定义时安排的顺序来传参。举个例子,有这样一个包含三个参数的函数:
def test(a, b, c):
print(f'{a}, {b}, {c}')
通过位置参数的方式来调用此函数:
test('1', '2', '3')
如果不想按参数顺序来调用函数,可以使用关键词参数,也就是指明参数名称的方式来调用:
test(c='3', a='1', b='2')
位置参数和关键词参数可以混用,但位置参数必须在前:
test('1', c='3', b='2')
形参
形参是 Python 比较特殊的一种参数定义方式,它有通过 *
和 **
两种前缀方式来定义:
def test(*args, **kwargs):
print(args)
print(kwargs)
调用上面的函数时,使用位置方式传递的参数会以元组类型赋值给 args
参数变量;通过关键词方式传递的参数会以字典方式赋值给 kwargs
:
>>> test('1', '2', c='3')
('1', '2')
{'c': '3'}
形参可以搭配普通参数定义使用,但必须位于其后,使用 **
的关键词形参必须位于最后。
def test(a, *args, **kwargs):
print(args)
print(kwargs)
限制参数传递方式
Python 函数提供两个特殊的符号,可以限制函数在调用时只能使用指定的方式传递参数,他们分别如下:
/
符号:符号前的参数只能以位置方式传递*
符号:符号后的参数只能以关键词方式传递
来看个例子:
def test(a, /, *, b, c):
print(f'{a}, {b}, {c}')
这个函数将只能以如下的方式调用:
test('1', b='2', c='3')
匿名函数
Python 提供了 lambda
关键词用作匿名函数功能,可以用来处理一些需要以函数方式处理,但又不需要复杂逻辑的场合。Lambda 匿名函数的使用格式如下:
lambda 参数 : 表达式
下面是使用匿名函数给列表数据按指定位置数据排序的例子:
items = [(1, 'a'), (2, 'c'), (3, 'b'), (4, 'd')]
items.sort(key=lambda item: item[1])