函数高级操作
一、命名空间
1 概念:保存对象和值的字典
2 分类
- 局部命名空间:函数内定义内容。
- 全局命名空间:模块级别,当前所有的py文件
- 内置命名空间:解释器级别,内置的方法等
3 访问命名空间
- locals():访问局部命名空间:根据调用的位置有关系
- globals():访问全局命名空间:与调用位置无关
4 加载顺序:从大到小
5 查找顺序:从小到大
# 情形1
id = 10
def func():
id = 20
print(id) # 20
func() #
# 情形2
id = 10
def func():
# id = 20
print(id) # 10
func()
# 情形3
# id = 10
def func():
# id = 20
print(id) # id函数
func()
二、作用域,局部变量和全局变量
1 概念
作用域:一个对象起作用的范围。
局部变量:仅在函数内部起作用的变量。
全局变量:在整个文件中起作用的变量。
2 作用域分类(LEGB)
-
Local(函数内部)局部作用域
-
Enclosing(嵌套函数的外层函数内部)嵌套作用域(闭包)
-
Global(模块全局)全局作用域
-
Built-in(内建)内建作用域
a = 10
def func():
b = 20
def inner():
c = 30
print(c)
inner()
print(b)
print(a)
问题:作用域和命名空间关系?
作用域是一个或多个命名空间叠加的结果。
注意:
在Python中,模块(module),类(class)、函数(def、lambda)会产生新的作用域。
三.global和nonlocal
注意:仅仅是修改操作时候需要声明。
- 将局部变量声明为全局变量:
global 变量名
# 情形1
n = 20
def func():
n = 30
print(n) # 30
func()
# 情形2
n = 20
def func():
# n = 30
print(n) # 20
func()
# 情形3
n = 20
def func():
# n = 30
print(n+1) # 21
func()
# 情形4
# n = 20
# def func():
# # n = 30
# n = n+1 # n 一定是局部变量
# print(n) # 报错
#
# func()
# print(n) #
# 情形5
n = 20
def func():
global n # 将声明为全局变量
n = n+1
print(n) # 21
func()
print(n) # 21
- 在函数嵌套中,将内层局部变量声明为外层局部变量
# 情形1
def func():
age = 20
def inner():
age = 30
print(age) # 30
inner()
print(age) # 20
func()
# 情形2
def func():
age = 20
def inner():
# age = 30
print(age) # 20
inner()
print(age) # 20
func()
# 情形3
def func():
age = 20
def inner():
# global age # 函数外无age变量,声明为全局变量会错误
nonlocal age # 将内层变量age声明为外层age
age = age + 1
print(age) # 30
inner()
print(age) # 21
func()
四.嵌套作用域
def f():
x = 4
action = lambda n,y=x:y**n
# def action(n,y=x):
# return y**n
return action
a = f()
# print(a)
b = a(3) # action(n,y=x)
print(b) # 4**3 = 64
d = a(3,3)
print(d) # 3**3=27
# 练习2:请说出li[0](2)的值,并且说明为什么
def f():
li = []
for i in range(5):
li.append(lambda x:i**x)
# def f2(x):
# return i**x
# li.append(f2)
return li
li = f()
print(li[0](3)) # i**3 4**3 = 64
print(li[1](3)) # i**3 4**3 = 64
print(li[2](3)) # i**3 4**3 = 64
print(li[3](3)) # i**3 4**3 = 64
print(li[4](3)) # i**3 4**3 = 64
# 如何改进是输出结果为: 0 1 8 27 64
def f():
li = []
for i in range(5):
# li.append(lambda x:i**x)
def f2(x,y=i):
return y**x
li.append(f2)
return li
li = f()
print(li[0](3)) # i**3
print(li[1](3)) # i**3
print(li[2](3)) # i**3
print(li[3](3)) # i**3
print(li[4](3)) # i**3