一、函数对象
1、函数对象:函数名存放的就是函数的地址,所以函数名也是对象,称之为函数对象
a = 10 print(a,id(a)) def fn(): num = 10 print('fn fuction run') print(fn()) b = a print(b,id(b))
2、函数对象的四个应用
①可以直接被引用fn=cp_fn
def fn(): num = 10 print('fn function run') print(fn) def fn(): num = 10 print('fn function run') func = fn print(fn) print(func)
②可以当做函数参数传递computed(cp_fn,a,b)
# 通过该函数可以对任意两个数的四则运算某一运算 def add(a,b): return a+b def low(a,b): return a-b def jump(a,b): return a*b def full(a,b): return a/b def computed(fn,a,b): # fn代表四则运算的一种,res为运算结果 res = fn(a,b) return res while True: cmd = input('cmd:>>>') if cmd =='add': result=computed(add,100,200) elif cmd =='low': result=computed(low,100,200) elif cmd =='jump': result=computed(jump,100,200) elif cmd =='full': result=computed(full,100,200) else: print('输入有误') print(result)
③可以作为容器类型的元素
def add(a,b): return a+b def low(a,b): return a-b def jump(a,b): return a*b def full(a,b): return a/b def quyu(a,b): return a %b def computed(fn,a,b): res = fn(a,b) return res method_map={ 'add':add, 'low':low, 'jump':jump, 'full':full, 'quyu':quyu, } while True: cmd = input('cmd:') # 用户输入的指令只要有对应关系,就会自动取走计算方法 if cmd in method_map: # 这样外界就不关心有哪些计算方法 cp_f = method_map[cmd] result = computed(cp_fn,100,200) print(result) else: print('输入错误') break
④可以作为函数的返回值
def add(a,b): return a +b def low(a,b): return a-b def jump(a,b): return a*b def full(a,b): return a/b def quyu(a,b): return a%b def computed(fn,a,b): res = fn(a,b) return res method_map = { 'add':add, 'low':low, 'jump':jump, 'full':full, 'quyu':quyu, } # 根据指令获取计算方法 def get_cp_fn(cmd): if cmd in method_map: return method_map[cmd] # 返回的是method_map中的’cmd’对应的值cmd return jump # 输入有误就采用jump while True: cmd = input('cmd:') if cmd =='quit': break cp_fn = get_cp_fn(cmd) result = computed(cp_fn,100,200) print(result)
二、名称空间
print(len('abc')) # 结果为 3 len = len('abcsdf') print(len) # 结果为 6 del len print(len('abc')) # 结果为 3 def fn1(): len = 100 print(len) def fn2(): len = 200 print(len) fn1() fn2()
1、定义:存放名字与内存空间地址对应关系的容器
2、作用:解决由于名字有限,导致名字重复发送冲突的问题
3、三种名称空间:
①build-in:内置名称空间,系统级,一个,随解释器执行而产生,解释器停止而销毁 ②global:全局名称空间,文件级,多个,随所属文件加载而产生,文件运行完毕而终止 ③local:局部名称空间,函数级,多个,随所属函数执行而产生,函数执行完毕而销毁 加载顺序:build-in>global>local
4、global关键词
可以将local的名字提升为global的名字。一个文件中的global名字就是一个,所以函数内外部使用的名字都是一个
注意:一定要调用函数,才能产生函数,并提升
# part1 len =1000 def fn(): len = 200 print(len) fn() # 结果为200 print(len) # 结果为1000 # part2 l = [] def fn(): l=[] l.append(200) print(l) fn() # 结果为 [200] print(l) # 结果为[] # 定义一个函数,函数中有一个变量 def fn1(): num = 200 return num fn1() # 在定义一个函数,该函数使用上一个函数的变量 def fn2(): print(num) num = fn1() fn2() # part3 num = 100 def fn1(): global num #100 # 将logal:num>global:num # 将局部上升到全局 num=200 num=300 # num=300 def fn2(): # logal中的名字一旦global,就变成global的名字,一个文件中的global就是一个 global num #300 num = 400 print(num) # num=400 fn1() print(num) # 结果为300 fn2() print(num) # 结果为300 400 400
三、作用域
1、定义:名字起作用的范围
2、作用:解决名字可以共存问题
3、四种作用域
①build-in:内置作用域,所有文件所有函数 ②global:全局作用域,当前文件所有函数 ③local:局部作用域,当前函数 ④enclosing:嵌套作用域,当前函数与当前函数的内部函数
len = 100 def outer(): len = 200 def inner(): len =300 print('1',len) # 结果为300 inner() print('2',len) # 结果为200 outer() print('3',len) # 结果为100 del len print('4',len) # 4 <built-in function len>
4、不同作用域之间名字不冲突,以达到名字的重用
查找顺序:local>enclosing>glocal>build-in
四、函数的嵌套定义和闭包
1、函数的嵌套定义:将函数直接定义到另一个函数的内部,可以使用外部函数中的名字
def fn1(): num = 200 def fn2(): # fn2就可以直接使用fn1中的名字 print(num) fn2() fn1()
2、闭包:
①closure:被包裹的函数称之为闭包。定义在函数内部的函数
②完整的闭包结构:
将函数进行闭包处理
提升函数名的作用域,将内部函数对象作为外部函数的返回值
def a(): def b(): print("cc") return b a() #a()=b y = a()() # a()() =b() y # 结果为 cc def a(): def b(): def c(): def d(): print('dddd') return d print("ccc") return c return b a() # b a()() #b() a()()() #b()() = c() a()()() y=a()()()() y # 结果为 dddd