名称空间 作用域 闭包

什么是名称空间

名称空间是存放名字的地方,对于x=1来说,1存放在内存中,x这个名字和x=1之间的绑定关系存放在名称空间中。

名称空间的加载顺序

对于test.py来说

1、Python解释器先启动,先加载内置名称空间
2、对于test.py这个文件,加载文件中的全局名称空间,如函数名,定义的变量名
3、在执行文件中的代码的时候,调用函数,临时产生局部名称空间

名字的查找顺序

局部名称空间--》全局名称空间--》内置名称空间

在全局无法查看局部的,在局部可以查看全局的

作用域

作用域就是范围

  • 全局作用域:内置名称空间、全局名称空间属于这个范围,全局存活,全局有效
  • 局部作用域:局部名称空间属于该范围,临时存活,局部有效

作用域在函数定义的时候就确定了,与函数的调用位置无关

查看作用域:globals(),locals()

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

闭包函数

内部函数包含对外部作用域而非全局作用域的引用

def counter():
    n = 0
    def incr():
        nonlocal n
        x = n
        n+=1
        return x
    return incr

c = counter() # c 就是函数incr
print(c)
print(c()) # 0
print(c()) # 1
print(c()) # 2
print(c()) # 3

print(c.__closure__[0].cell_contents) # 擦看闭包的元素

闭包的意义与作用

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

应用:延迟计算

import requests

def index(url):
    def get():
        response = requests.get(url)
        response.encoding = 'utf-8'
        return response.text
    return get
baidu = index('http://www.baidu.com')
print(baidu())

装饰器

装饰器是闭包函数的一种应用场景

一 为什么用装饰器

开放封闭原则:对修改封闭,对扩展开放

二 什么是装饰器

装饰器他人的器具,本身可以是任意可调用对象,被装饰者也可以是任意可调用对象。
强调装饰器的原则:1 不修改被装饰对象的源代码 2 不修改被装饰对象的调用方式
装饰器的目标:在遵循1和2的前提下,为被装饰对象添加上新功能

三 装饰器的使用

import time

def timer(func):
    def wrapper(*args,**kwargs):
        start_time = time.time()
        res = func(*args,**kwargs)
        stop_time = time.time()
        print('run time is %s'%(stop_time-start_time))
        return res
    return wrapper


@timer
def foo():
    time.sleep(3)
    print('foo run')
foo()
posted @ 2017-09-24 00:55  hzxPeter  阅读(160)  评论(0编辑  收藏  举报