1. for–else语法
for—else语法(用于处理遍历失败):
for里面有break就不走else
没有就走else
2.名称空间(命名空间)
- 当程序运行时,代码从上之下一次执行,他会将变量与值得关系存储在一个空间中。
- 当程序遇到函数时候,会将函数名存在内存中,函数体不关心。当函数执行时候,内存会临时开辟一个空间,存放函数体里面的变量,代码等,函数访问不到临时空间的内容,随着函数的执行完毕,临时的名称空间会释放掉。
2.1局部名称空间(局部名称空间)
向这个临时开辟的空间叫临时名称空间。
2.2内置名称空间
启动时候自动加载的语言中函数,例如:print。
2.3python 中名称空间分三种
- 内置名称空间;
- 全局名称空间;
- 局部名称空间(即:临时名称空间)
2.4作用域:
- 全局作用域:
内置名称空间
全局名称空间- 局部作用域:
局部名称空间
2.5加载顺序
内置名称空间加载到内存—>全局名称空间(当程序执行)—->局部名称空间
2.6取值顺序(单项不可逆)
局部名称空间(函数调用)—>全局名称空间(程序执行)—->内置名称空间
2.7函数嵌套
2.8内置函数globals(),locals()
- globals()返回一个字典,字典里面的内容是全局名称空间的内容
- locals()返回一个字典,当前位置(函数体内)的所有变量。
2.9global,nonlocal
对于可变的数据类型list,dict,set,不用global, nonlocal
list = []
def func():
list.append(666)
func()
print(list)
global
- a.引用并改变一个全局变量
- b.在局部作用域声明一个全局变量
count = 1
def func():
count = count + 1
print(count)
func()
print(count)
出现错误:local variable 'count' referenced before assignment
解决办法如下:
count = 1
def func():
global count
count = count + 1
print(count)
func()
print(count)
===================
def func():
global name
name = 'morgan'
print(name)
func()
print(name)
nonlocal
- a.不能操作全局变量(no binding for nonlocal ‘count’ found)
- b.从哪层引用的该变量,从那层开始全部改变
def func1():
count = 1
def inner():
count = count + 1
print(count)
inner()
func1()
========================
count = 1
def func1():
# count = 1
def inner():
nonlocal count
count = count + 1
print(count)
inner()
print(count)
func1()
=============================
def func1():
count = 1
def inner():
nonlocal count
count = count + 1
print(count)
def inner2():
pass
inner()
func1()
========================
def func1():
count = 1
def inner():
count = 9
count = count + 1
print(count)
inner()
print(count)
func1()
2.10取值
- 取值:引用而不是改变
- 取值是从小到大取值LEGB(local)
- 想改变上层空间的变量,要用到global,nonlocal
2.11函数名的应用(可以看作是变量)
第一类对象:像这样的函数名的叫法。
2.11.1函数名对应函数地址
2.11.2函数名可以作为容器类数据的元素
def func1():
print(111)
def func2():
print(222)
def func3():
print(333)
l1 = [func1,func2,func3]
for i in l1:
i()
2.11.3函数名可以作为函数的参数
def func1():
print(111)
def func2(x):
x()
print(222)
func2(func1)
2.11.4函数名可以作为函数的返回值
def func1():
print(111)
def func2(x):
print(222)
return x
func2(func1)() #func2(func1)=x=func1
2.11.5函数名可以任意赋值
def func1():
print(111)
return 111
f1 = func1
f2 = f1
f3 = f2
print(f3)
3.闭包
- 内层函数对外层函数非全局变量的引用。
- 是否是闭包的判断:
- 通过函数名.closure
- 如果python解释器遇到闭包,不会随着函数的结束而释放。
- 闭包用在装饰器,爬虫。
def wrapper(x):
def inner():
print(x)
inner()
print(inner.__closure__)
wrapper(name)
4.面试题补充
如果默认参数是一个可变的数据类型,那么他在内存中永远是一个。
def extendList(val,list=[]):
list.append(val)
return list
list1 = extendList(10) #[10]
list2 = extendList(123,[]) #[10,123]
list3 = extendList('a') #[10,123,'a']
print('list1=%s'%list1) #print:[10,a]
print('list2=%s'%list2) #print:[123]
print('list3=%s'%list3) #print:[10,a]
=================================
def extendList(val,list=[]):
list.append(val)
return list
list1 = extendList(10) #[10]
print('list1=%s'%list1)
list2 = extendList(123,[]) #[123]
print('list2=%s'%list2)
list3 = extendList('a') #[10,'a']
print('list3=%s'%list3)
5.装饰器
- 语法糖@
- 装饰器本质就是闭包
- 根本作用:在不影响原函数执行的基础上,增加一些额外的功能登陆认证,打印日志等等。
def wrapper(f):
def inner(*args,**kwargs):
"被装饰函数执行之前的操作"
ret = f(*args,**kwargs)
"被装饰函数执行之后的操作"
return ret
return inner