Python系统学习-04

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

猜你喜欢

转载自blog.csdn.net/weixin_41765871/article/details/80472240