函数对象
Python中一切皆对象
函数名也可以看成是变量名,那么它也同样具有变量名的三大特征
- 函数名对应的值
- type
- id
def self_max(x, y):
if x > y:
return x
return y
print(self_max)
print(type(self_max))
print(id(self_max))
<function self_max at 0x000001EF4A953840>
<class 'function'>
2127260104768
函数对象的四大功能
1.引用
def self_max(x, y):
if x > y:
return x
return y
a = self_max
num_max = a(10, 20)
print(num_max)
20
2.当作函数的返回值
def f1():
print('from f1')
def f2():
return f1
f = f2()
f()
from f1
3.当作函数的参数
def f1():
print('from f1')
def f2(m):
return m
f = f2(f1)
f()
from f1
4.作为容器元素中的元素
def f1():
print('from f1')
l = ['str', 1, f1]
l[2]()
from f1
def trans():
print('from trans')
def withdraw():
print('from withaw')
while True:
choice_dict = {'1': trans, '2': withdraw} # 这个直接打印tran的话是一大堆字符而不是我们想要的效果
choice_dict_user = {1: 'trans', 2: 'withdraw', 3: 'exit'}
print(choice_dict_user)
user_choice = input('请选择你需要的功能')
if user_choice == '3':
break
choice_dict[user_choice]()
{1: 'trans', 2: 'withdraw', 3: 'exit'}
请选择你需要的功能2
from withaw
{1: 'trans', 2: 'withdraw', 3: 'exit'}
请选择你需要的功能3
函数的嵌套
定义阶段识别语法,不运行代码
from math import pi
def circle(r, choice):
if choice == 'p':
def perimeter():
res = 2 * r * pi
return res
return perimeter()
if choice == 'a':
def area():
res = (r ** 2) * pi
return res
# area()
return area()
r = int(input('请输入半径'))
choice = input('求面积输入"a",求周长输入"p"')
print(circle(r, choice))
请输入半径3
求面积输入"a",求周长输入"p"a
28.274333882308138
名称空间和作用域
名称空间
- 存放函数名的空间
1.内置名称空间
- 如'str'.strip() # 所学的所有内置方法,其实就是一个个函数,这些函数被封装后用来实现一个个功能
- 各种数据类型都有各自的内置方法,Python也有Python的内置方法,比如len(),在Python启动的时候,就会定义len()函数,并且把len()丢入内存空间,这个内存空间就叫做内置名称空间
- 生命周期:Python启动的时候就活了,关闭就死了
2.全局名称空间
- 除了内置和局部,就是全局
- 生命周期:程序/文件运行的时候才会活,运行完毕就死了
3.局部名称空间
- 函数内部的都叫局部, 也就是说函数内部定义的名字都放入了局部名称空间中了.
- 生命周期:函数运行的时候会活,运行完就死了
考试必考
- 执行顺序: 内置名称空间--> 全局名称空间--> 局部名称空间
- 查找顺序: 从当前名称空间开始查找,找到就停下,找不到就往上找.只往上找,不往下找
作用域
- 全局作用域: 适用于全局+内置,即全局可以修改内置的,内置可以修改全局的
- 局部作用域: 只能适用于局部范围,在局部定义的名字只能在局部获取
- 作用域关系在函数定义阶段就已经确定了
x = 100
def f1():
x = 2
def f2():
x = 3
print('f1',x)
return f2
f2 = f1()
x = 1000
def f3():
x = 15
f2()
f3()
f1 1000
- 自我理解:全局只有一个,而局部可以有很多个,如果两个局部间是包含嵌套的关系,那么外部函数的变量可以适用于内部函数,如果两个局部是平行关系,那么没有任何关系.
global
- 局部修改全局
x = 100
def f1():
global x
x = 1
f1()
print(x)
1
nonlacal
- 在函数嵌套中把局部改成外部
def f1():
x = 1
def f2():
nonlocal x
x = 3
f2()
print(x)
f1()
3
LEGB原则
- L(Local)局部作用域
- E(Enclosing function locale)外部嵌套函数作用域
- G(Global module)函数定义所在模块作用域
- B(Buildin):Python内置模块的作用域
- 里面可以访问外面的变量,外面无法访问里面的变量,越靠近优先级越高(局部变量注意是包含还是平行)