函数
函数是程序中可复用的代码块。你可以给这段代码块起名字,也就是函数名。然后在程序中的任意地方去调用它。我们已经使用过内置的一些函数,比如range()
, len()
。
函数也许是成功软件里最重要的一个组成部分,下面我们将会详述函数的各个部分。
函数使用关键字def
来定义,紧跟着关键字的是函数名,后面的一对小括号里有保存传入参数的变量,在这一行的最后有个冒号,表示下面的语句块属于该函数。下面是一个简单的例子:
例子(保存至function1.py
):
def say_hello():
#属于函数的语句块
print('你好,中国!')
say_hello()#调用函数
say_hello()#调用函数
输出:
$ python function1.py
你好,中国!
你好,中国!
它是怎么运作的呢?
我们定义了一个函数say_hello()
,然后调用了两次。该函数没有传入参数,因此括号里没有变量。参数是函数的输入,因此我们可以传入不同的值,然后得到不同的返回值。
注意,我们调用了两次函数,也就是说,不用重复写代码了!
函数参数
函数可以接收多个参数,也就是你提供给函数的变量,函数可以使用这些变量,完成某个功能。参数和变量不同之处 - 参数直到调用函数的时候才会被赋值。
在函数定义的时候,参数用小括号括住,参数之间用逗号分隔。当要调用该函数时,要类似的提供参数值。注意,我们这里用的专业术语-在定义函数时,括号里的叫做参数,在调用函数时,括号里的叫做参数值。
例子(保存至function_param.py
):
def print_max(a, b):
if a > b:
print(a, '第一个数大。')
elif a == b:
print('两个数一样大。')
else:
print(b, '第二个数大。')
print_max(3, 4)
x = 6
y = 7
print_max(x, y)
输出:
$ python function_param.py
4 第二个数大。
7 第二个数大。
它是怎么运作的呢?
我们定义了一个叫做print_max
的函数,该函数有两个参数a
和b
。我们用if语句去找到两个数中较大的一个数,然后把它打印出来。
第一次调用print_max
,我们直接把数值当作参数值;第二次调用print_max
,我们把变量当作参数值,print_max(x, y)
把x的值赋给a,把y的值赋给b。两种情况下,print_max
函数有着相同的运作方式。
局部变量
你在函数里定义的变量,与函数外的同名变量没有任何关系;也就是说,对于函数,变量名是局部的。这种情况叫做变量的作用域。变量在哪里代码块里定义的,它的作用域就在哪个代码块里, 变量作用域从定义的地方开始,直到代码块的结束位置。
例子(保存至function_local.py
):
x = 50
def func(x):
print('x 的值:', x)
x = 2
print('变成局部变量x的值:', x)
func(x)
print('外部x的值:', x)
输出:
$ python function_local.py
x 的值: 50
变成局部变量x的值: 2
外部x的值: 50
它是怎么运作的呢?
第一次打印的x值,在函数体的第一行,它用主代码块传进的参数值。
接下来我们把2赋值给x,x的名字只在该函数的内部生效。所以当我们在函数里改变了x的值,并不会对主代码块的x造成影响(名空间)。
全局变量
如果你想定义一个全局变量,你仅需要告知Python,这个变量名不是局部的,是全局的,就可以了。我们将使用全局变量声明。在函数里给函数外部的变量赋值,一定要使用全局变量声明。
你可以在函数里使用函数外的变量。然而这不是一个好的代码习惯,应该避免这样做,它会让你的代码不清晰,难以阅读,因为读者不知道变量定义在何处。全局变量的声明就适用在这种情况。
例子(保存至function_global.py
):
x = 50
def func():
global x
print('x的值是:', x)
x = 2
print('变成了全局变量x:', x)
func()
print('外部x的值是:', x)
输出:
$ python function_global.py
x的值是: 50
变成了全局变量x: 2
外部x的值是: 2
它是怎么运作的呢?
全局变量声明,声明x是一个全局变量,因此外部的x可以在函数里被赋值,当然外部的x值也相应的发生了改变。
在一个全局变量声明中,你可以指定多个全局变量。比如,global x, y, z。
默认的参数值
一些函数,你可能想让一些参数是可选的,也就是说在调用的时候对这些参数可以传入参数值也可以不传入参数值,当不传入参数值的时候,函数使用该参数的默认值。参数的默认值应该在定义函数的时候定义,也就是在参数后面添加操作符=和默认值。
注意,参数的默认值必须是一个常量,准确说,参数的默认值是不能被修改的。下面的章节会对不能被修改的值做阐述。现在,记住这点就可以了。
例子(保存至function_default.py
):
def say(message, times=1):
print(message*times)
say('你好')
say('驴子', 5)
输出:
$ python function_default.py
你好
驴子驴子驴子驴子驴子
它是怎么运作的呢?
函数say
用来打印字符串指定的次数。如果没有提供打印的次数,会取默认值也就是1, 那么将会打印字符串一次。可以看到,我们在定义函数的时候指定了打印次数的默认值。
在第一次调用say
时,只传入了一个字符串参数,它把字符串打印了一次;第二次调用时,传入了字符串和次数,因此它把字符串打印了5次。
注意:
只有在参数列表最后端的参数能有默认值,也就是说带有默认值的参数不能在没有默认值的参数前面,哈,有点拗口。
这是因为参数依据参数列表的位置进行赋值,比如说,def func(a, b=5)是一个有效的函数,而def func(a=5, b)是一个非法的函数。
关键字参数
有些函数可能有很多参数,并且你想通过指定名字来传入参数值,这种方式叫做关键字传参。这种情况,我们使用关键字代替位置进行传参。
这种传参方式有两个优点:
- 函数更容易使用:因为不需要担心忘记参数的顺序。
- 我们可以只传入我们想要传入的参数。
例子(保存至function_keyword.py
):
def func(a, b=5, c=6):
print('a is %s, b is %s, c is %s' % (a, b, c))
func(3, 7)
func(3, c=25)
func(b=23, a=3)
输出:
$ python function_keyword.py
a is 3, b is 7, c is 6
a is 3, b is 5, c is 25
a is 3, b is 23, c is 6
它是怎么运作的呢?
函数func
有一个不带默认值的参数,后面有两个带有默认值的参数。
第一次调用函数,func(3, 7),通过位置传参,a被赋值3, b被赋值7, c取默认值。
第二次调用函数,func(3, c=25), 通过关键字和位置传参,a被赋值3, b取默认值5, c被赋值25。
第三次调用函数,func(b=23, a=3), 通过关键字传参,a被赋值3, b被赋值23, c取默认值6。
VarArgs参数
有时,你可能想要定义一个可以接收任意多个参数的函数,也就是接收个数可变的参数。可以通过使用星号来达成。
例子(保存至function_varargs.py
):
def total(a=5, \*numbers, \*\*phonebook):
print('a', a)
for i in numbers:
print(i)
for key, value in phonebook.items():
print('关键字', key)
print('值', value)
print(total(10, 1, 2, 3, jack=1123, john=2231, inge=1560))
输出:
a 10
1
2
3
关键字 jack
值 1123
关键字 john
值 2231
关键字 inge
值 1560
None
它是怎么运作的呢?
一个星号参数,表示所有位置参数值的集合。
双星参数与它类似,表示所有关键字参数值的集合。
return语句
return语句用来从函数返回,也就是,跳出函数,但是可以从函数返回一个值。
例子(保存至function_return.py
):
def maxmum(x, y):
if x > y:
return x
elif x == y:
return '一样大'
else:
return y
print(maxmum(2, 3))
输出:
$ python function_return.py
3
它是怎么运作的呢?
maxmum
函数返回参数中最大的数,该函数用简单的if..else语句去找最大的数,然后返回这个数。
注意,一个不带值的return语句等同于return None
。None
是Python的一个特殊类型,表示无。比如说,可以用它来表示一个变量没有值。
如果你没有给函数写return语句,那么函数结尾处会隐式包含一个return None语句。some_function()
没有写return语句,当执行print(some_function())
时,会打印一个None。
def some_function():
pass
pass语句表示一个空的语句块。
小提示:
内置的max函数用来找最大数,当要找最大数时,尽量用它。
文档字符串
Python有个非常棒的特性,叫做文档字符串。文档字符串是一个重要的工具,它给程序做批注,让程序更容易理解。更棒的是,我们还可以获取到在执行状态的程序的文档字符串。
例子(保存至function_docstrings.py
):
def print_max(x, y):
'''
打印两个数中最大的数,这两个数必须是整数。
'''
if x > y:
print(x, '是最大数')
else:
print(y, '是最大数')
print_max(3, 5)
print(print_max.__doc__)
输出:
$ python function_docstrings.py
打印两个数中最大的数,这两个数必须是整数。
它是怎么运作的呢?
在函数体第一行的注释内容就是该函数的文档字符串。注意,模块和类也有文档字符串,在后面的内容将会学到。
文档字符串,必须是多行字符串。书写惯例:第一段简单介绍功能,第二段是详细的介绍,两段间间隔一行。
如何获取文档字符串呢?在本例中,print_max
函数通过它的属性__doc__
来获取文档字符串。记住,Python所有都是对象,当然包括函数。
如果你用过help()
,你就会明白文档字符串的作用。help
所作的就是获取函数的doc属性值,然后把它漂亮的打印出来。你可以试试它,在程序中加入代码help(print_max.__doc__)
。记住,按q
键退出帮助窗口。
Python自动从你的程序中收集文档字符串。因此,推荐你在写的有用函数加上文档字符串。发布的Python项目有pydoc命令,它与使用help获取文档字符串类似。
总结
我们学习了函数的很多知识。但是依旧有些内容没有覆盖到。
下一章节,我们将学习使用、创建模块。