10python(第十天日记)

1.名称空间:     存放名字的地方,三种名称空间,(之前遗留的问题x=1,1存放于内存中,那名字x存放在哪里呢?名称空间正是存放名字x与1绑定关系的地方)

  1.全局命名空间:代码在运行伊始,创建的存储“变量名与值的关系”的空间

  2.局部命名空间:在函数的运行中开辟的临时的空间叫做

  3.内置命名空间:存放了python解释器为我们提供的本来就有函数的名字

  

  三种命名空间之间的加载与取值顺序:

  加载顺序:内置命名空间(程序运行前加载)->全局命名空间(程序运行中:从上到下加载)->局部命名空间(程序运行中:调用时才加载)

  取值顺序:

    在局部调用:局部命名空间->全局命名空间->内置命名空间

注释:在全局无法查看局部的,在局部可以查看全局的,如下示例

max=1
def f1():
    max=2
    def f2():
        max=3
        print(max)
    f2()
f1()
print(max)

 

    在全局调用:全局命名空间->内置命名空间

  综上所述,在找寻变量时,从小范围,一层一层到大范围去找寻。

2.作用域

  全局作用域,局部作用域。

  全局作用域:全局名称空间,内置名称空间

  局部作用域:局部名称空间

#1、作用域即范围
        - 全局范围(内置名称空间与全局名称空间属于该范围):全局存活,全局有效
      - 局部范围(局部名称空间属于该范围):临时存活,局部有效
#2、作用域关系是在函数定义阶段就已经固定的,与函数的调用位置无关,如下
x=1
def f1():
    def f2():
        print(x)
    return f2
x=100
def f3(func):
    x=2
    func()
x=10000
f3(f1())

#3、查看作用域:globals(),locals()


LEGB 代表名字查找顺序: locals -> enclosing function -> globals -> __builtins__
locals 是函数内的名字空间,包括局部变量和形参
enclosing 外部嵌套函数的名字空间(闭包中常见)
globals 全局变量,函数定义所在模块的名字空间
builtins 内置模块的名字空间

 

3.函数的嵌套

  代码从上至下依次执行, 调用函数:函数里面从上至下依次执行。

print(111)
def func1():
    print(333)
    func2()
    print(666)

def func2():
    print(444)

def func3():
    print(555)
func1()
print(222)
>>>111 333 444 666 222
print(globals())  全局名称空间:所有变量
print(locals()) 局部名称空间:所有变量

 

4.关键字

  在基本的python语法当中,一个函数可以随意读取全局数据,但是要修改全局数据的时候有两种方法:  1 global 声明全局变量 2 全局变量是可变类型数据的时候可以修改

  global:在局部空间内,声明一个全局变量

  nonlocal: 在局部空间内改变一个全局变量。在局部作用域中,对上一级作用域(非全局作用域)的变量进行引用和修改,并且引用的哪层,从那层及以下此变量全部发生改变。

b = 4
def add_b():
    b = 42
    def do_global():
        nonlocal b
        b = 10
        print(b)
        def dd_nonlocal():
            global b
            b = b + 20
            print(b)
        dd_nonlocal()
        print(b)
    do_global()
    print(b)
add_b()
print(b)
>>>10
>>>24
>>>10
>>>10
>>>24

 5.函数名的应用

     函数名是函数的名字,本质:变量,特殊的变量。       函数名() : 执行此函数。

    1.单独打印函数名  : <function func1 at 0x0000000000872378>

    2.函数名的赋值

def func2():
    print(666)
f = func2
print(f())
>>>666

 

    3.函数名可以作为容器类数据的元素

def f1():
    print(1211)
def f2():
    print(1222)
l1 = [f1, f2,]
for i in l1:
    i()
>>>1211
>>>1222

 

    4.函数名可以作为参数

def f1():
    print(666)
def f2(x):  # x = f1
    x()  # f1()
f2(f1)
>>>666

 

    5.函数名可以作为函数的返回值。

def f1():
    print(666)
def f2(x):  # x = f1
    return x
ret = f2(f1)  # f1
ret()
>>>666

 

6.闭包

  在一个外函数中定义了一个内函数,内函数里运用了外函数的临时变量,并且外函数的返回值是内函数的引用。这样就构成了一个闭包。

  闭包:就是内层函数对外层函数(非全局)变量的引用。     如何判断:  内层函数名.__closure__      cell 就是=闭包

  闭包的意义:返回的函数对象,不仅仅是一个函数对象,在该函数外还包裹了一层作用域,这使得,该函数无论在何处调用,优先使用自己外层包裹的作用域

   from urllib.request import urlopen
'''
上面:提取 url文件
下面:作一个闭包返回函数调用
'''
def index(url): def get(): return urlopen(url).read() return get baidu=index('http://www.baidu.com') print(baidu().decode('utf-8'))

 

  应用领域:延迟计算(原来我们是传参,现在我们是包起来)

name = '老男孩'
def wraaper2(n):
     # n = '老男孩' 相当于
    def inner():
        print(n)
    inner()
    print(inner.__closure__)  #  None
wraaper2(name)

 

  闭包:当函数开始执行时,如果遇到了闭包,他有一个机制,他会永远开辟一个内存空间,将闭包中的变量等值放入其中,不会随着函数的执行完毕而消失。

 

posted on 2018-03-29 21:02  小鸡刨粑粑  阅读(81)  评论(0编辑  收藏  举报

导航