- 一 名称空间
- 1.1 内建名称空间
- 1.2 全局名称空间
- 1.3 局部名称空间
- 二 作用域
- 2.1 全局作用域与局部作用域
- 2.2 作用域与名字查找的优先级
**args与kwargs:**
def index(a,b,c):
print(a,b,c)
def wrapper(*args,**kwargs): # args=(1,2,3) kwargs={}
index(*args,**kwargs) # index(*(1,2,3) ,**{}) # index(1,2,3)
wrapper(1,2,3)
**内建名称空间**
伴随python解释器的启动/关闭而产生/回收,因而是第一个被加载的名称空间,
用来存放一些内置的名字,比如内建函数名
>>> max
<built-in function max> #built-in内建
**全局名称空间**
伴随python文件的开始执行/执行完毕而产生/回收,是第二个被加载的名称空间,
文件执行过程中产生的名字都会存放于该名称空间中,如下名字
import sys #模块名sys
x=1 #变量名x
if x == 1:
y=2 #变量名y
def foo(x): #函数名foo
y=1
def bar():
pass
Class Bar: #类名Bar
pass
**局部名称空间**
伴随函数的调用/结束而临时产生/回收,函数的形参、函数内定义的名字都会被存放于该名称空间中
def foo(x):
y=3 #
**总结:**
调用函数时,才会执行函数代码,名字x和y都存放于该函数的局部名称空间中
名称空间的加载顺序是:内置名称空间->全局名称空间->局部名称空间,而查找一个名字,
必须从三个名称空间之一找到,查找顺序为:局部名称空间->全局名称空间->内置名称空间。
**函数的嵌套调用**:
在调用一个函数的过程中,又调用了其他函数
def max2(x,y):
if x > y:
return x
else:
return y
def max4(a,b,c,d):
res1 = max2(a,b)
res2 = max2(res1,c)
res3 = max2(res2,d)
print(res3)
max4(1,2,3,4)
**函数的嵌套定义**: 在函数内又定义了一个函数
def f1(): # 定义在函数内部的内容有一个效果:函数外无法访问,只有在函数内才可以访问到
x = 111
print(x)
f1()
# print(x)
def f1():
def f2():
print('from f2')
f2()
f1()
# f2()
from math import pi
def circle(radius,mode=0):
def perimiter(radius):
return 2 * pi * radius
def area(radius):
return pi * (radius ** 2)
if mode == 0:
return perimiter(radius)
elif mode == 1:
return area(radius)
print(circle(3,0))
**函数的对象**
def foo(): # foo->函数的内存地址
print('from foo')
1、可以被赋值
f = foo
f() # from foo
2、可以当做参数传入
def f1(func):
print('====>f1')
func()
f1(foo) # f1(函数的内存地址) # from foo
3、可以当做返回值
def f1(func):
return func
f = f1(foo)
print(f)
4、可以当做容器类型的元素
x = 10
l = [x,foo,foo()]
# print(l)
l[1]()
def login():
print('登录功能'.center(50, '*'))
def register():
print("注册功能".center(50, '*'))
def transfer():
print("转账功能".center(50, '*'))
def withdraw():
print("提现功能".center(50, '*'))
func_dic = {
"1": ['登录功能', login],
"2": ['注册功能', register],
"3": ['转账功能', transfer],
"4": ['提现功能', withdraw],}
while True:
print("0 退出")
for k in func_dic:
print(k,func_dic[k][0])
choice = input("请输入命令编号:").strip()
if choice == "0":
break
if choice in func_dic:
func_dic[choice][1]()
else:
print("输入的指令错误")
**名称空间与作用域**
名称空间Namespace:存放名字与内存地址绑定关系的地方
内置名称空间:存放python解释器自带的名字
print(len)
print(input)
全局名称空间: 存放的是顶级的名字,如下x、z、f1、xxx都是
x = 100
def f1():
y = 200
if 10 > 3:
z = 300
if True:
xxx = 400
局部名称空间:存放的是函数内定义的名字
def f1():
x = 200
f1()
**重要结论1**:局部Local-》外层函数Enclosing-》全局Global-》内置Builtin
L->E->G->B
例1:
def f1():
# len = 200
print(len)
len = 100
f1()
print('=====>',len)
例2:LEGB
len = 100
def f1():
# len = 200
def f2():
# len = 300
print(len)
len = 1111111111111111111111111111111111111111111
f2()
f1()
**重要结论2**:名称空间的嵌套关系是在函数定义阶段、扫描语法时就确定好的,与调用位置无关
# 例1:
len = 100
def f1():
# len = 200
def f2():
print(len)
return f2
f = f1()
# print(f)
len = 6666666666666
f()
例2:
len = 100
def f1():
def f2():
print(len)
# len = 200
return f2
f = f1()
def foo():
len = 77777
f()
foo()
例3 :报错 例子
x = 100
def f1():
print(x)
x = 200
f1()
**总结:**
全局作用域:全局存活,全局有效
内置名字空间、全局名称空间
局部作用域:临时存活,局部有效
局部名称空间
局部是可以直接修改可变数据类型
=============》 global关键字
l = []
x = 100
def foo():
l.append(333)
global x
x = 200(x=100不会改变,除非在x=200 前添加global x,
global作用主要是修改全局不可变数据类型的)
foo()
print(l)
print(x)
=============》 nonlocal(e外层函数)关键字
x = 111
def f1():
# x = 222
def f2():
# global x(改的是全局名称的x)
nonlocal x(改的是外层函数的x)
x = 333
f2()
print('==========>f1肚子里的x: ',x)
f1()
print(x)
**闭包函数:**
闭函数:定义在函数内部的函数
def outter():
def wrapper():
print('====>wrapper')
包函数: 内部函数引用了一个来自于外层函数的变量
def outter():
x = 111
def wrapper():
print('====>wrapper',x)
为函数体传参的两种方案
方案一:直接通过参数传入即可
def wrapper(x):
print('====>wrapper',x)
wrapper(111)
wrapper(222)
方案二:闭包函数
def outter(x):
def wrapper():
print('====>wrapper',x)
return wrapper # 不要加括号
new_wrapper1 = outter(111)
new_wrapper1()
new_wrapper2 = outter(222)
new_wrapper2()