一、函数作用域:
1 #1、作用域即范围
2 - 全局范围(内置名称空间与全局名称空间属于该范围):全局存活,全局有效
3 - 局部范围(局部名称空间属于该范围):临时存活,局部有效
4 #2、作用域关系是在函数定义阶段就已经固定的,与函数的调用位置无关,如下
5 x=1
6 def f1():
7 def f2():
8 print(x)
9 return f2
10 x=100
11 def f3(func):
12 x=2
13 func()
14 x=10000
15 f3(f1())
16
17 #3、查看作用域:globals(),locals()
18
19
20 LEGB 代表名字查找顺序: locals -> enclosing function -> globals -> __builtins__
21 locals 是函数内的名字空间,包括局部变量和形参
22 enclosing 外部嵌套函数的名字空间(闭包中常见)
23 globals 全局变量,函数定义所在模块的名字空间
24 builtins 内置模块的名字空间
二、函数式编程:
1 #1、首先强调:面向过程编程绝对不是用函数编程这么简单,面向过程是一种编程思路、思想,而编程思路是不依赖于具体的语言或语法的。言外之意是即使我们不依赖于函数,也可以基于面向过程的思想编写程序
2
3 #2、定义
4 面向过程的核心是过程二字,过程指的是解决问题的步骤,即先干什么再干什么
5
6 基于面向过程设计程序就好比在设计一条流水线,是一种机械式的思维方式
7
8 #3、优点:复杂的问题流程化,进而简单化
9
10 #4、缺点:可扩展性差,修改流水线的任意一个阶段,都会牵一发而动全身
11
12 #5、应用:扩展性要求不高的场景,典型案例如linux内核,git,httpd
13
14 #6、举例
15 流水线1:
16 用户输入用户名、密码--->用户验证--->欢迎界面
17
18 流水线2:
19 用户输入sql--->sql解析--->执行功能
ps:函数的参数传入,是函数吃进去的食物,而函数return的返回值,是函数拉出来的结果,面向过程的思路就是,把程序的执行当做一串首尾相连的功能,该功能可以是函数的形式,然后一个函数吃,拉出的东西给另外一个函数吃,另外一个函数吃了再继续拉给下一个函数吃。。。
三、函数式编程举例:
1 #=============复杂的问题变得简单
2 #注册功能:
3 #阶段1: 接收用户输入账号与密码,完成合法性校验
4 def talk():
5 while True:
6 username=input('请输入你的用户名: ').strip()
7 if username.isalpha():
8 break
9 else:
10 print('用户必须为字母')
11
12 while True:
13 password1=input('请输入你的密码: ').strip()
14 password2=input('请再次输入你的密码: ').strip()
15 if password1 == password2:
16 break
17 else:
18 print('两次输入的密码不一致')
19
20 return username,password1
21
22 #阶段2: 将账号密码拼成固定的格式
23 def register_interface(username,password):
24 format_str='%s:%s\n' %(username,password)
25 return format_str
26
27 #阶段3: 将拼好的格式写入文件
28 def handle_file(format_str,filepath):
29 with open(r'%s' %filepath,'at',encoding='utf-8') as f:
30 f.write(format_str)
31
32
33 def register():
34 user,pwd=talk()
35 format_str=register_interface(user,pwd)
36 handle_file(format_str,'user.txt')
37
38
39 register()
40
41
42 #=============牵一发而动全身,扩展功能麻烦
43 #阶段1: 接收用户输入账号与密码,完成合法性校验
44 def talk():
45 while True:
46 username=input('请输入你的用户名: ').strip()
47 if username.isalpha():
48 break
49 else:
50 print('用户必须为字母')
51
52 while True:
53 password1=input('请输入你的密码: ').strip()
54 password2=input('请再次输入你的密码: ').strip()
55 if password1 == password2:
56 break
57 else:
58 print('两次输入的密码不一致')
59
60
61 role_dic={
62 '1':'user',
63 '2':'admin'
64 }
65 while True:
66 for k in role_dic:
67 print(k,role_dic[k])
68
69 choice=input('请输入您的身份>>: ').strip()
70 if choice not in role_dic:
71 print('输入的身份不存在')
72 continue
73 role=role_dic[choice]
74
75 return username,password1,role
76
77 #阶段2: 将账号密码拼成固定的格式
78 def register_interface(username,password,role):
79 format_str='%s:%s:%s\n' %(username,password,role)
80 return format_str
81
82 #阶段3: 将拼好的格式写入文件
83 def handle_file(format_str,filepath):
84 with open(r'%s' %filepath,'at',encoding='utf-8') as f:
85 f.write(format_str)
86
87
88 def register():
89 user,pwd,role=talk()
90 format_str=register_interface(user,pwd,role)
91 handle_file(format_str,'user.txt')
92
93
94 register()
95
96
97 #ps:talk内对用户名\密码\角色的合法性校验也可以摘出来做成单独的功能,但本例就写到一个函数内了,力求用更少的逻辑来为大家说明过程式编程的思路
98
99 示例:复杂的问题变得简单,但扩展功能麻烦