函数嵌套定义

目录

局部变量  全局变量

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())
globals

def 语句             创建函数
lambda表达式    创建函数

1 myhello = lambda : print("hello world")
2 >>> v = print("hello world")
3 hello world
4 >>> print(v)
5 None
View Code

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绑定的函数
function_variable.py
 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)
give_function_as_args.py
 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'])
give_function_as_args2.py

看懂如下代码:

 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  
myinput

函数可以作为另一个函数的返回值
示例见:

1 def fx():
2     return max
3 
4 
5 fn = fx()
6 print(fn([1, 3, 5, 7]))
return_function.py

函数的嵌套定义
函数嵌套定义是指一个函数里用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()
View Code
  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
View Code

语法:
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)  # 
global.py


说明:
1. 全局变量如果要在函数内部被赋值,则必须经过全局声明(否则会被认为是创建局部变量)
2. 全局变量在函数内部不经过声明就可以直接访问(变量已经存在并关联一个对象)

1 def fn():
2     n = v  # 出错,v 变量没有被定义
3     print(n)
4 
5 v = 100 # 和放前面一样
6 fn()
example

3. 不能先声明局部变量,再用global声明为全局变量,此做法不附合规则

v = 100
def fn():
    v = 200 # 创建局部变量
    global v # 此时至少是警告,不建议这样写
    v = 300
    print(v)  # 300,修改的不知是局部还是全局变量

fn()
print('v= ',v) # 300
example

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
example



写一个函数叫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次
hello

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)
nonlocal.py
 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
View Code


说明:
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()
View Code

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
View Code

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
lambda


说明:
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
View Code

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
View Code

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)
eval

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当成程序来执行
exec

练习:
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))
answer

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))
answer


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)
answer

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()
answer
原文地址:https://www.cnblogs.com/Alan-Song/p/9665740.html