目录
局部变量 全局变量
locals() globals()
一个函数可以作为参数传入另一个函数
传入一个函数
函数可以作为另一个函数的返回值
不加括号绑定函数, 加括号调用函数语句
函数嵌套定义
python四个作用域
局部作用域 nonlocal语句
外部嵌套函数作用域 global语句
全局作用域
内建模块的作用域
1 # globals() #函数 2 a=1 3 b=2 4 c=3 5 def fx(c,d): 6 e=300 7 # 此处有几个局部变量 3个 8 print('locals()返回',locals()) 9 # locals()返回 {'c': 100, 'e': 300, 'd': 200} 10 print('globals()返回',globals()) 11 # globals()返回 {'c': 3, 'b': 2, 'a': 1,....} 12 # 'fx': <function fx at 0x7effe5346f28>} 13 print(c) # 100 14 print(globals()['c']) #3 15 16 fx(100,200) 17 print(globals())
def 语句 创建函数
lambda表达式 创建函数
1 myhello = lambda : print("hello world") 2 >>> v = print("hello world") 3 hello world 4 >>> print(v) 5 None
eval(s)函数
...表达式....
exec(s)函数
....语句(程序).....
globals() / locals()函数:
globals() 返回当前全局作用域内变量的字典
locals() 返回当前局部作用域内变量的字典
示例见:
1 def fa(): 2 print("hello world") 3 4 5 f1 = fa # <<<---这里没有括号,f1 变量绑变的是函数 6 f1() # 调用 fa绑定的函数 7 fa() # 调用 fa绑定的函数
1 def f1(): 2 print("hello") 3 4 5 def f2(): 6 print("world") 7 8 9 f1, f2 = f2, f1 10 11 f1() # world 12 f2() # hello
函数变量
1 def fa(): 2 print("hello f1") 3 4 f1 =fa # 这里没有括号,f1变量绑定的是函数 5 f1() # 调用 fa 绑定的函数 'hello f1', 6 fa() # 调用 fa 绑定的函数 'hello f1', 7 f1 = fa() #绑定的是fa调用完之后的结果
函数名是变量,它在def 语句创建函数时绑定一个函数
示例见:
1 def f1(): 2 print("hello") 3 4 5 def f2(): 6 print("world") 7 8 9 f1, f2 = f2, f1 10 11 f1() # world 12 f2() # hello
一个函数 可以作为另一个函数的实参传递
示例见:
1 def f1(): 2 print("f1被调用") 3 4 5 def f2(): 6 print("f2被调用") 7 8 9 def fx(fn): 10 print(fn) 11 fn() # 此时这是调用什么呢? 12 13 14 fx(f1) 15 fx(f2)
1 def goodbye(L): 2 for x in L: 3 print("再见:", x) 4 5 6 def hello(L): 7 for x in L: 8 print("你好:", x) 9 10 11 def operator(fn, L): 12 fn(L) 13 14 15 operator(hello, ['Tom', 'Jerry', 'Spike'])
看懂如下代码:
1 def myinput(fn): 2 L = [5, 3, 1, 9, 7] 3 return fn(L) 4 5 print(myinput(max)) 6 print(myinput(min)) 7 print(myinput(sum)) 8 print(myinput(len)) 9 10
函数可以作为另一个函数的返回值
示例见:
1 def fx(): 2 return max 3 4 5 fn = fx() 6 print(fn([1, 3, 5, 7]))
函数的嵌套定义
函数嵌套定义是指一个函数里用def语句来创建其它的函数的情况
示例:
1 def fn_outter(): 2 print("fn_outter被调用") 3 def fn_inner(): 4 print("fn_inner被调用") 5 fn_inner() 6 fn_inner() 7 print("fn_outter调用结束") 8 9 fn_outter()
1 def fa(): 2 print("hello f1") 3 4 f1 =fa # 这里没有括号,f1变量绑定的是函数 5 f1() # 调用 fa 绑定的函数 'hello f1', 6 fa() # 调用 fa 绑定的函数 'hello f1', 7 f1 = fa() #绑定的是fa调用完之后的结果 8 # ------------------------------------ 9 # 此示例示例函数变量的赋值 10 def f1(): 11 print("hello") 12 def f2(): 13 print("world") 14 15 f1,f2 = f2,f1 # 序列赋值,交换 16 f1() # 'world' 17 f2() # 'hello' 18 19 # ----------------------------------------- 20 def f1():# 清扫工 21 print("f1被调用") 22 def f2():# 洗碗工 23 print("f2被调用") 24 def fx(fn):# 保洁公司 25 print("fn绑定的是",fn) 26 fn() # 调用fn绑定的函数,此处调用谁就看调用者传过来谁 27 28 fx(f1) 29 fx(f2) 30 31 # ------------------------------------------------- 32 def goodbye(L): # 函数和函数之间最好空两行 33 for x in L: 34 print("再见:",x) 35 36 37 def hello(L): 38 for x in L: 39 print("你好:",x) 40 41 42 def operator(fn,L): 43 fn(L) 44 45 # fn 调用 goodbye 的函数 46 operator(goodbye,['Tom','Jerry','Spike']) 47 operator(hello,['Tom','Jerry','Spike']) 48 49 # -------------------------------------------- 50 def myinput(fn): 51 L = [5,3,1,9,7] 52 return fn(L) 53 54 #fn是变量,能绑定任意函数 55 print(myinput(max)) 56 print(myinput(min)) 57 print(myinput(sum)) 58 print(myinput(len)) 59 60 # ------------------------------------ 61 # 函数可以作为另一个函数的返回值 62 def fx(): 63 return max 64 65 fn = fx() #调用fn 等同于调用 fx 66 print(fn([1,3,5,7])) 67 68 # ------------------------ 69 def get_op(): 70 s = input("请输入您要做的操作:") 71 if s== '求最大': 72 return max 73 elif s == '求最小': 74 return min 75 elif s == '求和': 76 return sum 77 78 79 L=[2,4,6,8,10] 80 print(L) 81 f=get_op() # 得到一个操作 82 print(f(L)) 83 84 # ----------------------------------- 85 # 函数嵌套 86 def fx(): 87 i = 100 88 L = [1,2,3,4] 89 def f1(): 90 print("f1被调用") 91 f1() 92 93 fx() # "f1被调用" 94 95 # ----------------------------- 96 # 函数嵌套 97 def fn_outter(): 98 print('fn_outter 被调用') 99 def fn_inner(): 100 print('fn_inner 被调用') 101 fn_inner() 102 fn_inner() 103 print('fn_outter调用结束') 104 105 fn_outter()
写一个计算公式的解释执行器
已知有如下一些函数:
def myadd(x, y):
return x + y
def mysub(x, y):
return x - y
def mymul(x, y):
return x * y
写一个函数,传入字符串,返回相应的函数
1 def get_op(s): 2 if s == '+' or s == '加': 3 return myadd 4 elif s == '-' or s == '减': 5 return mysub 6 elif s == '*' or s == '乘': 7 return mymul
# 此函数根据字符串来返回相应的函数.
# 如果传入字符串"加" 则返回myadd函数
# .... '乘',则返回mymul函数
... 此处自己实现
主程序如下:
1 while True: 2 s = input("请输入计算公式:") # 10 加 20 3 L = s.split() 4 print(L) 5 a = int(L[0]) 6 b = int(L[2]) 7 fn = get_op(L[1]) 8 print("结果是:",fn(a,b)) # 30
python 的作用域
作用域也叫名字空间,是访问变量时查找变量名的范围空间
python的四个作用域:
作用域 英文解释 英文缩写
局部作用域(函数内) Local(function) L
外部嵌套函数作用域 Enclosing function locals E
函数定义所在模块(文件)作用域 Global(module) G
Python内建模块的作用域 Builtin(Python) B
示例见:
1 v=100 # 第1步 2 def f1(): # 第2步 3 v=200#如果没有,到外部找 #100 # 第4步 4 print('f1.v=',v) # 200 # 第5步 5 def f2(): # 第6步 6 v=300 #如果没有,到外部找 #200 # 第8步 7 print("f2.v=",v) #300 # 第9步 8 f2() # 第7步 9 f1() # 第3步 10 print("全局的v=",v) #100
变量名的查找规则
在变量访问时,先查找本地变量,然后是包裹此函数外部的函数内部的变量,之后是全局变量,最后是内建变量
即:
L ----> E ----> G ----> B
在默认的情况下,变量名赋值会创建或者改变当前作用域的变量
global 语句
作用:
1. 告诉解释执行器 global 语句声明的一个或多个变量,这些变量的作用域为模块级的作用域,也称作全局变量
2. 全局声明(global)将赋值语句操作的变量映射到模块文件内部的作用域
1 v = 100 2 def fn(): 3 v = 200 4 print('fn 内的v=',v) # 200 5 6 fn() 7 print('v= ',v) # 100
语法:
global 变量1, 变量2, ...
示例见:
1 v = 100 2 def fn(): 3 global v # 声明v 是全局,此时不允许在此作用域存在v 4 v = 200 # 想让此语句去修改全局作用域内的变量 v 5 print('fn 内的v=',v) # 200 6 7 fn() 8 print('v= ',v) #
说明:
1. 全局变量如果要在函数内部被赋值,则必须经过全局声明(否则会被认为是创建局部变量)
2. 全局变量在函数内部不经过声明就可以直接访问(变量已经存在并关联一个对象)
1 def fn(): 2 n = v # 出错,v 变量没有被定义 3 print(n) 4 5 v = 100 # 和放前面一样 6 fn()
3. 不能先声明局部变量,再用global声明为全局变量,此做法不附合规则
v = 100 def fn(): v = 200 # 创建局部变量 global v # 此时至少是警告,不建议这样写 v = 300 print(v) # 300,修改的不知是局部还是全局变量 fn() print('v= ',v) # 300
4. global变量列表里的变量名不能出现在此作用域的形参列表里
1 v = 100 2 def fx(v): 3 global v # 出错 name 'v' is parameter参数 and global 4 print(v) # 200 5 6 fx(200) 7 print('v= ',v) # 100
写一个函数叫hello(name),部分代码如下:
count = 0
def hello(name):
print('你好', name)
... 此处代码省略,需要填写
... 此处代码需要改变全局变量来记录此函数曾经被调用过多少次.
hello('小张')
hello('小李')
print('hello 函数被调用', count, '次') # 2次
1 def hello(name): 2 print("你好",name) 3 global count 4 count += 1 5 6 hello("小张") 7 hello("小李") 8 print('hello 函数被调用',count,'次') # 2次
nonlocal 语句
作用:
告诉解释执行器,nonlocal声明的变量不是局部变量,也不是全局变量,它是外部嵌套函数内的变量
语法:
nonlocal 变量名1, 变量名2, ....
示例见:
1 # 此示例示意nonlocal 声明语句的用法 2 var = 100 3 4 5 def outter(): 6 var = 200 7 print("outter内的var=", var) 8 9 def inner(): 10 nonlocal var 11 var = 300 12 print("inner内的var=", var) 13 inner() 14 print("outter结束时的var=", var) 15 16 outter() 17 print('全局的var=', var)
1 # 此示例示意 nonlocal声明语句的用法 2 var = 100 3 4 def outter(): 5 nonlocal var # 报错 6 var = 200 7 print('outter 内的var=',var) # 200 8 def inner(): 9 nonlocal var # 256行结果变成 300 10 # global var # 那258行的结果就是300 11 var = 300 12 print('inner内的var=',var) # 300 13 inner() 14 print('outter结束时的var=',var) # 200 15 16 outter() 17 print("全局的var=",var) # 100
说明:
1. nonlocal 语句只能在被嵌套的函数内部进行使用
2. 访问nonlocal变量将对外部嵌套函数作用域内的变量进行操作
3. 当有两层或两层以上函数嵌套时,访问nonlocal变量只对最近的一层变量进行操作
1 v = 100 2 def f1(): 3 v = 200 4 def f2(): 5 v = 300 6 def f3(): 7 nonlocal v # 279行的结果变成400 8 v = 400 9 print('f3.v=',v) # 400 10 f3() 11 print('f2.v=',v) # 300 12 f2() 13 print('f1.v=',v) # 200 14 f1()
4. nonlocal语句的变量列表里的变量名,不能出现在此函数的参数列表中
1 var = 100 2 def outter(): 3 var = 200 4 print('outter 内的var=',var) # 200 5 6 def inner(var): 7 # 出错 name 'var' is parameter参数 and nonlocal 8 nonlocal var # 256行结果变成 300 9 var = 300 10 print('inner内的var=',var) # 300 11 inner() 12 print('outter结束时的var=',var) # 200 13 14 outter() 15 print("全局的var=",var) # 100
def 语句
作用:
创建函数
lambda 表达式(又称匿名函数)
作用:
创建一个匿名函数对象
同 def 类似,但不提供函数名
格式:
lambda : 表达式
示例见:
1 # 此示例示例 lambda 表达式的用法 2 3 def myadd(x,y): 4 return x + y 5 6 myadd = lambda x, y: x + y # 同 def 函数功能相同 7 8 print('20 + 30 =',myadd(20,30)) # 50 9 print('40 + 50 =',myadd(40,50)) # 90
说明:
1. lambda 只是一个表达式,它用来创建一个函数对象
2. 当lambda表达式调用时,先执行冒号(:)后的表达式,并返回表达式的结果的引用关系
3. lambda 表达式创建的函数只能包含一条表达式
4. lambda 比函数简单且可以随时创建和销毁,有利于减少程序的偶合度
练习:
1. 写一个lambda 表达式,判断这个数的2次方+1是否能被5整除,如果能被整除返回True, 否则返回False
例:
fa = lambda x: .....
print(fa(2)) # True
print(fa(4)) # False
1 fa = lambda n:(n ** 2 + 1) % 5 == 0
2. 写一个lambda表达式,求两个变量的最大值
例如:
def mymax(x, y):
...
mymax = lambda ...
print(mymax(100, 200)) # 200
1 def mymax(x,y): 2 if x > y: 3 return x 4 else: 5 return y 6 7 mymax=lambda x,y:max(x,y) 8 mymax = lambda x,y: x if x > y else y 9 print(mymax(100,200)) # 200
eval() / exec() 函数
eval(source, globals=None, local=None) 把一个字符串 srouce 当成一个表达式来执行,返回表达式执行的结果
exec(source, globals=None, locals=None) 把一个字符串source 当成程序来执行
eval示例见:
1 # eval 1 2 x = 100 3 y = 200 4 5 a = eval('x + y') 6 print(a) # 300 7 8 a = eval('x + y',{'x':1,'y':2}) # 全局作用域 9 print(a) # 3 10 11 a = eval('x + y', 12 {'x':1,'y':2}, # 全局作用域 13 {'x':10,'y':20}) # 局部作用域 14 print(a) # 30 15 16 a = eval('x + y', 17 {'x':1,'y':2}, 18 {'x':10}) 19 print(a) # 12 20 21 22 # eval 2 23 while True: 24 s = input("请输入表达式") 25 if not s: 26 break 27 a = eval(s) 28 print(a)
exec 示例见:
1 # exec 2 3 s = '''print('hello world') 4 x = 100 5 x += 200 6 print('x=',x) 7 ''' 8 9 exec(s) # 把s当成程序来执行
练习:
1. 给出一个整数n,写一个函数myfac来计算n!(n的阶乘)
n! = 1 * 2 * 3 * 4 * ..... * n
如:
print(myfac(5)) # 120
1 def myfac(n): 2 i = 1 3 for x in range(1, n+1): 4 i *=x 5 return i 6 7 print(myfac(5))
2. 给出一个整数n,写一个函数计算myfn(n):
1 + 2**2 + 3**3 + .... + n**n的和
如:
print(myfn(10))
1 def myfn(n): 2 s = 0 3 for i in range(1, n+1): 4 s += i**i 5 return s 6 7 print(myfn(10))
3. 完全数:
1 + 2 + 3 = 6 (6为完全数)
1,2,3都为6的因数(因数是能被一个数x整除的整数为y,则y为x的因数)
1 x 6 = 6
2 x 3 = 6
完全数是指除自身以外的所有因数相加之和等于自身的数
求 4~5个完全数并打印出来
答案:
6
28
496
......
1 def wqs(y): 2 l = [] 3 for x in range(1, y): 4 for a in range(1, x): 5 if x % a == 0: 6 l.append(a) 7 if sum(l) == x: 8 print(x) 9 else: 10 print('不是完全数') 11 12 13 print(wqs(1000)) 14 15 16 17 def wqs(y): 18 s = [] 19 for i in range(1, y): 20 t = [] 21 for d in range(1,i): 22 if i % d == 0: 23 t.append(i) 24 if sum(t) == i: 25 s.append(t) 26 return s 27 28 print(wqs(1000)) 29 30 for n in range(1, 10000000): 31 s = 0 32 for i in range(1, n): 33 if n %i == 0: 34 s +=i 35 36 if s ==n: 37 print(n)
4 实现带有界面的学生信息管理系统
程序启动时先弹出操作菜单:
+-------------------------+
| 1) 添加学生信息 |
| 2) 显示学生信息 |
| 3) 删除学生信息 |
| 4) 修改学生成绩 |
| q) 退出 |
+-------------------------+
请选择: 1
要求 :
每个选择都要有一个函数来实现
1 def input_student(): 2 L = [] # 创建一个容器准备放入 3 while True: 4 name = input('请输入姓名: ') 5 if not name: # 如果名字为空,结束输入操作 6 break 7 age = int(input("请输入年龄: ")) 8 score = int(input("请输入成绩: ")) 9 d = {} # 每次都会执行{} 来创建新的字典 10 d['name'] = name 11 d['age'] = age 12 d['score'] = score 13 L.append(d) 14 return L 15 16 17 def output_student(lst): 18 # 打印表格 19 print("+---------------+----------+----------+") 20 print("| name | age | score |") 21 print("+---------------+----------+----------+") 22 for d in lst: 23 n = d['name'].center(15) 24 a = str(d['age']).center(10) 25 s = str(d['score']).center(10) 26 print("|%s|%s|%s|" % (n, a, s)) 27 28 print("+---------------+----------+----------+") 29 30 31 def show_menu(): 32 print('+-------------------------+') 33 print('| 1) 添加学生信息 |') 34 print('| 2) 显示学生信息 |') 35 print('| 3) 删除学生信息 |') 36 print('| 4) 修改学生成绩 |') 37 print('| q) 退出 |') 38 print('+-------------------------+') 39 40 41 def main(): 42 docs = [] # 用于存放学生信息的空列表 43 while True: 44 show_menu() 45 s = input("请选择: ") 46 if s == '1': 47 docs += input_student() 48 elif s == '2': 49 output_student(docs) 50 elif s == '3': 51 print("开始删除") 52 elif s == '4': 53 print("开始修改成绩") 54 elif s == 'q': 55 break 56 57 main()