# 函数-应用
# 定长参数(不包含默认值)
## 求任意三个数的乘积
def mul(a,b,c):
print(a*b*c)
## 根据不同的用户名显示不同的欢迎信息
def welcome(username):
print('欢迎',username,'光临')
1
2
3
4
5
6
7
2
3
4
5
6
7
# 定长参数(包含默认值)
## 定义形参时,可以为形参指定默认值
## 指定了默认值以后,如果用户传递了参数则默认值没有任何作用
## 如果用户没有传递,则默认值就会生效
def fn(a = 5 , b = 10 , c = 20):
print('a =',a)
print('b =',b)
print('c =',c)
## fn(1 , 2 , 3)
## fn(1 , 2)
## fn()
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
# 不定长的参数
## 定义一个函数,可以求任意个数字的和
def sum(*nums):
# 定义一个变量,来保存结果
result = 0
# 遍历元组,并将元组中的数进行累加
for n in nums :
result += n
print(result)
## sum(123,456,789,10,20,30,40)
## 在定义函数时,可以在形参前边加上一个*,这样这个形参将会获取到所有的实参
## 它将会将所有的实参保存到一个元组中
## a,b,*c = (1,2,3,4,5,6)
## *a会接受所有的位置实参,并且会将这些实参统一保存到一个元组中(装包)
def fn(*a):
print("a =",a,type(a))
## fn(1,2,3,4,5)
## 带星号的形参只能有一个
## 带星号的参数,可以和其他参数配合使用
## 第一个参数给a,第二个参数给b,剩下的都保存到c的元组中
def fn2(a,b,*c):
print('a =',a)
print('b =',b)
print('c =',c)
## 可变参数不是必须写在最后,但是注意,带*的参数后的所有参数,必须以关键字参数的形式传递
## 第一个参数给a,剩下的位置参数给b的元组,c必须使用关键字参数
def fn2(a,*b,c):
print('a =',a)
print('b =',b)
print('c =',c)
## 所有的位置参数都给a,b和c必须使用关键字参数
def fn2(*a,b,c):
print('a =',a)
print('b =',b)
print('c =',c)
## 如果在形参的开头直接写一个*,则要求我们的所有的参数必须以关键字参数的形式传递
def fn2(*,a,b,c):
print('a =',a)
print('b =',b)
print('c =',c)
## fn2(a=3,b=4,c=5)
## *形参只能接收位置参数,而不能接收关键字参数
def fn3(*a) :
print('a =',a)
## **形参可以接收其他的关键字参数,它会将这些参数统一保存到一个字典中
## 字典的key就是参数的名字,字典的value就是参数的值
## **形参只能有一个,并且必须写在所有参数的最后
def fn3(b,c,**a) :
print('a =',a,type(a))
print('b =',b)
print('c =',c)
fn3(b=1,d=2,c=3,e=10,f=20)
## 参数的解包(拆包)
def fn4(a,b,c):
print('a =',a)
print('b =',b)
print('c =',c)
## 创建一个元组
t = (10,20,30)
## 传递实参时,也可以在序列类型的参数前添加星号,这样他会自动将序列中的元素依次作为参数传递
## 这里要求序列中元素的个数必须和形参的个数的一致
fn4(*t)
## 创建一个字典
d = {'a':100,'b':200,'c':300}
## 通过 **来对一个字典进行解包操作
fn4(**d)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# 作用域和命名空间
## 作用域指的是变量生效的区域
## 在Python中一共有两种作用域
## 全局作用域
## - 全局作用域在程序执行时创建,在程序执行结束时销毁
## - 所有函数以外的区域都是全局作用域
## - 在全局作用域中定义的变量,都属于全局变量,全局变量可以在程序的任意位置被访问
##
## 函数作用域
## - 函数作用域在函数调用时创建,在调用结束时销毁
## - 函数每调用一次就会产生一个新的函数作用域
## - 在函数作用域中定义的变量,都是局部变量,它只能在函数内部被访问
##
## 变量的查找
## - 当我们使用变量时,会优先在当前作用域中寻找该变量,如果有则使用,
## 如果没有则继续去上一级作用域中寻找,如果有则使用,
## 如果依然没有则继续去上一级作用域中寻找,以此类推
## 直到找到全局作用域,依然没有找到,则会抛出异常
## NameError: name 'a' is not defined
b = 20 # 全局变量
def fn():
a = 10 # a定义在了函数内部,所以他的作用域就是函数内部,函数外部无法访问
print('函数内部:','a =',a)
print('函数内部:','b =',b)
fn()
## 命名空间(namespace)
## 命名空间指的是变量存储的位置,每一个变量都需要存储到指定的命名空间当中
## 每一个作用域都会有一个它对应的命名空间
## 全局命名空间,用来保存全局变量。函数命名空间用来保存函数中的变量
## 命名空间实际上就是一个字典,是一个专门用来存储变量的字典
## locals()用来获取当前作用域的命名空间
## 如果在全局作用域中调用locals()则获取全局命名空间,如果在函数作用域中调用locals()则获取函数命名空间
## 返回的是一个字典
scope = locals() # 当前命名空间
print(type(scope))
print(a)
print(scope['a'])
## 向scope中添加一个key-value
scope['c'] = 1000 # 向字典中添加key-value就相当于在全局中创建了一个变量(一般不建议这么做)
## print(c)
def fn4():
a = 10
# scope = locals() # 在函数内部调用locals()会获取到函数的命名空间
# scope['b'] = 20 # 可以通过scope来操作函数的命名空间,但是也是不建议这么做
# globals() 函数可以用来在任意位置获取全局命名空间
global_scope = globals()
# print(global_scope['a'])
global_scope['a'] = 30
# print(scope)
fn4()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# 闭包
## 形成闭包的要件
## ① 函数嵌套
## ② 将内部函数作为返回值返回
## ③ 内部函数必须要使用到外部函数的变量
def make_averager():
# 创建一个列表,用来保存数值
nums = []
# 创建一个函数,用来计算平均值
def averager(n) :
# 将n添加到列表中
nums.append(n)
# 求平均值
return sum(nums)/len(nums)
return averager
averager = make_averager()
print(averager(10))
print(averager(20))
print(averager(30))
print(averager(40))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 装饰器
def begin_end(old):
'''
用来对其他函数进行扩展,使其他函数可以在执行前打印开始执行,执行后打印执行结束
参数:
old 要扩展的函数对象
'''
# 创建一个新函数
def new_function(*args , **kwargs):
print('开始执行~~~~')
# 调用被扩展的函数
result = old(*args , **kwargs)
print('执行结束~~~~')
# 返回函数的执行结果
return result
# 返回新函数
return new_function
def fn3(old):
'''
用来对其他函数进行扩展,使其他函数可以在执行前打印开始执行,执行后打印执行结束
参数:
old 要扩展的函数对象
'''
# 创建一个新函数
def new_function(*args , **kwargs):
print('fn3装饰~开始执行~~~~')
# 调用被扩展的函数
result = old(*args , **kwargs)
print('fn3装饰~执行结束~~~~')
# 返回函数的执行结果
return result
# 返回新函数
return new_function
@fn3
@begin_end
def say_hello():
print('大家好~~~')
say_hello()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44