python中函数可以作为容器对象的元素_函数对象

Python-12

@(Python)

一、函数对象

函数是第一类对象,意思是函数可以被当做数据处理

函数对象:就是函数不带括号

函数对象,可以将定义在函数内的函数,通过return返回值,返回到全局中使用,从而打破函数的层级限制

Python中一切皆对象

func和func()的区别

func()是函数的返回值

func函数名记录了值的内存地址(记录了值的内存地址,相当于连接函数名和值的线),函数名就是函数的内存地址

print(func)打印的是func函数名记录的值的内存地址

print(func())打印的是func函数的返回值

1528352438108.png

① 函数名可以被用来引用(赋值给一个变量)

# func是一个函数

y=x

f=func

print(f) # 就相当于print(func)

f() # f()就相当于func()调用函数

② 函数名当做参数传给一个函数

1528353082407.png

③ 函数名可以当做函数的返回值

1528353428363.png

④ 函数名可以当做容器类型的元素

可以把函数的内存地址(或理解为函数名的内存地址),当做元素

1528353853976.png

利用函数名为容器类型的元素,来调用函数

# 取款

def qk():

print('取款成功')

# 转账

def zz():

print('转账成功')

# 支付

def zf():

print('支付成功')

func_dict={

'1':qk,

'2':zz,

'3':zf,

}

while True:

msg='''

1. 取款

2. 转账

3. 支付

4. 退出

'''

print(msg)

func_num=input('输入数字>>')

if func_num == '4' : break

if func_num not in func_dict:

print('不在范围')

continue

func_dict[func_num]()

二、函数的嵌套

1. 函数的嵌套定义

函数的嵌套是在函数中再定义函数

在函数内中定义的函数,只能在这个函数内使用(一般情况下)

def func1():

def func2():

print('函数2')

通过函数嵌套,将一个大功能的小功能嵌套进去,不同的功能汇聚到一起,类似于封装成一个工具箱

例子:利用函数嵌套和函数对象当做容器元素,来写出计算圆面积和周长的功能

from math import pi # 计算圆的公式需要调用

def yuan(banjing,action):

def mianji():

return pi * (banjing ** 2)

def zhouc():

return pi * banjing * 2

if action == 'mianji':

return mianji() # 这是yun函数的返回值

elif action == 'zhouc':

return zhouc()

func1=input('半径>>')

func1=int(func1)

func2=input('计算类型>>')

print(yuan(func1,func2)) # 也可以使用默认形参固定一个常用的类型

2. 函数的嵌套调用

使用函数嵌套,在调用一个函数时,也调用了其他函数

如果一个功能可以被重复调用,就可以单独做成一个功能,使用其他函数再调用

1528363280815.png

三、名称空间与作用域

1. 名称空间

专门用来存名字的空间(变量名、函数名等的内存地址)

名称空间,是存放名字和值绑定关系的地方

① 内置名称空间

内置命名空间:Python解释器自带的名字

生命周期:在解释器启动时生效,在解释器关闭时失效

② 全局名称空间

全局名称空间:除了内置和局部空间外,其余都是全局名称空间

全局名称空间,是在文件执行时产生的(顶头写的代码使用的就是全局名称空间)

生命周期:在文件执行时生效,在文件执行完毕后失效

③ 局部名称空间

存放函数调用期间函数体产生的名字,即函数内定义的名字

生命周期:执行文件时,只有被调用了才会临时生效,在函数执行完毕后失效,自动释放

内置、全局、局部名称空间的加载顺序

① 内置名称空间--->② 全局名称空间--->③ 局部名称空间

内置、全局、局部名称空间的查找顺序

① 局部名称空间--->② 全局名称空间--->③ 内置名称空间

基于当前位置,然后按顺序找

1528367049260.png

1528367305327.png

2. 作用域

作用域就是名称空间的作用的范围,是对名称空间的再分类

① 全局作用域

全局作用域:就是全局作用范围,包括:内置名称空间和全局名称空间

全局有效:内置命名空间和全局命名空间

全局存活:从程序开始存活,一直到程序的结束

② 局部作用域

局部作用域:就是局部作用范围,包括:局部命名空间

局部有效,临时存活

作用域关系是在函数定义阶段就固定好了,但凡要调用函数就需要去函数的定义阶段找作用域关系

1528369648998.png

x=10

def func1():

print(x)

x=10000000000000000000000

def func2():

x=11111111111

func1()

func2() # 以调用为分隔符,往前找

1528369263826.png

1528371048255.png

x=10

def func1():

x=777777777777777777 # 先找局部空间,再找全局空间,全局空间有多个找上面最近的

print(x)

x=10000000000000000000000

def func2():

x=11111111111

func1()

func2() # 以调用为分隔符,往前找

③ 作用域的应用:

打破层级限制,利用return将函数名转到全局,再调用

1528370374637.png

1528370496110.png

def f1():

def inner():

print('from inner')

return inner

f1()() # f1()得到的是return的值,相当于inner,f1()() == inner()

# 或者

f=f1()

f() # 相当于f1()()

1528371197055.png

def f1():

x=1

def inner():

print('from inner',x)

return inner

f=f1() # 相当于f=inter

def bar():

x=11111111111111

f() # 相当于inter()

bar()

说明:回到定义阶段,按照先局部,后全局的顺序找,如果局部没有才找全局,如果有多个全局,就以调用函数为分隔线,往上找最近的

在函数体内,改全局的东西,需要使用global x,比如global x将x拿到全局用,同代码段往下找最后一个

但是尽量不要改全局,尽量做成独立的功能,对其他无影响

x=1

def foo():

global x

x=111

foo()

print(x)

nonlocal会往本函数体外层找,往上找最近的,但是还是在大的函数内,找到就改,找不到就报错

x=1

def f1():

def f2():

x=2222222 # 找到的内容

def f3():

nonlocal x

x=111111111111 # 要改成什么

f3()

print(x) # 打印这一层的,看nonlocal是后生效

f2()

f1()

1528372858450.png

在局部如果想要修改全局的可变类型,不需要借助任何声明,可以直接修改,比如可以改字典,列表等

在局部如果想要修改全局的不可变类型,需要借助global声明,声明为全局的变量就可以直接修改

1528373198205.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值