函数
函数的定义
函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段。简单的说函数是为实现一个操作而集合在一起的语句集。例如之前用到的随机数函数random.randint(a, b),但调用这个函数时,系统就会执行函数里的这些语句,并返回结果。
定义一个函数
函数包括函数头和函数体,函数头。函数头以一个def关键字开始,后面紧接着函数名已经形参并以冒号结束。函数头中的参数被称为形式参数简称为形参。参数就像一个占位符,当调用函数时,就讲一个值传递给参数,这个值被称为实际参数或实参。函数的参数是可选的,也就是说,函数可以不包含参数,同样的到来函数可以有返回值,也可以没有返回值。
说明:函数定义主要包括函数名称、形参、以及函数体,函数可以用来定义可重用代码,组织和简化代码。
函数的语法
def function_name(parameters):
"""函数文档注释"""
function_body
return [expression]
说明:默认情况下,参数值和参数名称是按函数声明中定义的的顺序匹配起来的。
函数参数
- 关键字参数
在有参数的函数中参数和函数关系密切,在没有指定使用关键字的情况下,输入的参数必须和定义函数时指定的参数顺序一致,否则便会报错。在Python中使用关键字参数向函数传递参数时,允许参数的顺序和定义函数时的参数顺序不一致,且不会报错,示例如下:
# 定义打印名字和年龄的函数
def print_name_age(name, age):
print('Name is:', name)
print('Age is:', age)
# 调用打印名字和年龄的函数
print_name_age(age=18, name='zhang')
Name is: zhang
Age is: 18
- 默认参数
指定了默认值得参数,函数的参数允许设置默认值,在函数被调用时,如果没有传入值,则以默认值传入函数。下例会打印默认的age,如果age没有被传入:
# 定义打印名字和年龄的函数
def print_name_age(name, age=18):
print('Name is:', name)
print('Age is:', age)
# 调用打印名字和年龄的函数
print_name_age('zhang')
print_name_age('zhang', 18)
Name is: zhang
Age is: 18
Name is: zhang
Age is: 18
说明:在使用默认参数时,如果不是所有参数都都赋予默认值,那么定义函数时应注意将所有带默认值得参数放在后面,将必备参数放前面,否则会报错。如果所有参数都带有默认值,当我们调用函数时对其中某个参数(除第一个)传递指定值时应使用关键字参数。
- 不定长参数
当我们需要设计一个函数,这个函数要能够接受参数,但是又不能确定传入这个函数的参数个数的时候,我们需要用到一个特别的参数。这参数叫做不定长参数,和上述2种参数不同,声明时不用为每个参数命名,在某个参数前面加星号(*)那么参数就会存放所有未命名的变量参数。示例如下:
# 在参数前使用*表示args是可变参数
# 也就是说调用add函数时传入的参数个数可以是0个或多个
def add(*args):
total = 0
for val in args:
total += val
return total
print(add())
print(add(1))
print(add(1, 2))
print(add(1, 2, 3))
print(add(1, 3, 5, 7, 9))
0
1
3
6
25
函数返回值
在函数定义中使用return关键字来定义函数返回的值,return关键字后面可以是一个表达式,可以是一个或多个常量、变量,或者是布尔值。不带return语句的函数默认返回的值是None。
# 定义一个带多个返回值的函数
def foo():
a = 1
b = 2
return a,b,(a + b)
def thy():
a = 1
print(foo())
print(thy())
(1, 2, 3)
None
说明:当函数返回多个值时,函数返回值时存在一个元组里面的。
变量作用域
相信在写了这么久的小程序中一定遇到过"UnboundLocalError: local variable 'n' referenced before assignment"的错误。这是为什么呢?在Python 中,程序的变量并不是在哪个位置都可以访问的,访问权限决定于这个变量是在哪里赋值的。变量的作用域决定了在哪一部分程序可以访问哪个特定的变量名称。
在Python中变量遵循LEGB原则:L(local)-->E(enclosing)-->G(global)-->B(build-in)。即:在局部找不到,便会去局部外的局部找,再找不到就会去全局找,全局都找不到就会去Python内建中找。实际上我们用的最多的应该是全局变量和局部变量:
全局变量和局部变量
定义在函数内部的变量拥有一个局部作用域,定义在函数外的拥有全局作用域。
局部变量只能在其被声明的函数内部访问,而全局变量可以在整个程序范围内访问。调用函数时,所有在函数内声明的变量名称都将被加入到作用域中
total = 0; # 定义一个全局变量
def sum( arg1, arg2 ):
#返回2个参数的和."
total = arg1 + arg2; # total在这里是局部变量.
print ("函数内是局部变量 : ", total)
return total;
#调用sum函数
sum( 10, 20 );
print ("函数外是全局变量 : ", total)
函数内是局部变量 : 30
函数外是全局变量 : 0
global 和 nonlocal关键字
当内部作用域想修改外部作用域的变量时,就要用到global和nonlocal关键字了。
以下实例修改全局变量 num:
num = 1
def fun1():
global num # 需要使用 global 关键字声明
print(num)
num = 123
print(num)
fun1()
1
123
def outer():
num = 10
def inner():
nonlocal num # nonlocal关键字声明
num = 100
print(num)
inner()
print(num)
outer()
100
100
总结:
函数除了可以用来定义可重用代码,组织和简化代码,所以我认为函数还可以是代码模块化,就好比一个蛋糕如果要一次做好是很难的,我们可以拆分为多个模块一点一点的做好了,最后拼接起来这么做一个蛋糕就很容易了,我们写程序也是这样,要想一次写好一个程序也是很难的,但是将一个程序划分为多个模块,然后将这些模块拼起来就可以很简单很快速的完成一个程序了。
网友评论