day4_python之名称空间与作用域、闭包函数、嵌套函数

一、名称空间与作用域

名称空间:存放名字的地方,准确的说名称空间是存放名字与变量值绑定关系的地方

内置名称空间:在python解释器启动时产生,存放一些python内置的名字
全局名称空间:在执行文件时产生,存放文件级别定义的名字
x=1
def func():
    y=2
    def f1():pass
    print


import os

class Foo:
    pass

if x==1:z=3

del x


局部名称空间:在执行文件的过程中,如果调用了函数,则会产生该函数的局部名称空间
用来存放该函数内定义的名字,该名字在函数调用时生效,在函数调用结束后失效



加载顺序:内置---》全局---》局部


优先掌握一:名字的查找顺序是:局部-》全局-》内置

# max=1
def foo():
    max=2
    # print(max)

foo()
print(max)




x=0
def f1():
    x=1
    def f2():
        x=2
        def f3():
            x=3
            print(x)
        f3()
    f2()
    print('=f1========',x)


f1()




def func1():
    print('from func1')

def func1():
    print('=====?>')

func1()

x=1
x=10
print(x)
View Code

 

1、什么是名称空间?

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

2、名称空间的加载顺序

python test.py
#1、python解释器先启动,因而首先加载的是:内置名称空间
#2、执行test.py文件,然后以文件为基础,加载全局名称空间
#3、在执行文件的过程中如果调用函数,则临时产生局部名称空间

3、名字的查找顺序

复制代码
局部名称空间--->全局名称空间--->内置名称空间

#需要注意的是:在全局无法查看局部的,在局部可以查看全局的,如下示例

# max=1
def f1():
    # max=2
    def f2():
        # max=3
        print(max)
    f2()
f1()
print(max) 
复制代码

二、作用域

作用域:作用的范围,
全局作用域:全局存活,全局有效:globals()
max=1111111
def f1():
    def f2():
        def f3():
            def f4():
                # print(x)
                print(max)
            f4()
        f3()
    f2()


f1()
局部作用域:临时存活,局部有效:locals()

x=11111111111111111111111111111111111111111111

def f1():
    x=1
    y=2
    def f2():pass
    # print(locals())
    print(globals())

f1()
print(locals() is globals())
print(locals())

print(dir(globals()['__builtins__']))


--------------------------------------------------
global nonlocal掌握    :global 修改全局的
x=1
def f1():
    global x       明确声明x就是全局的x ,所以就会把全局的x=1,改成局部的x=2。
    x=2

f1()
print(x)
-----------------------------------------------

l=[]
def f2():
    l.append('f2')    能直接把l的值改‘f2’,因为l是列表,列表是可变类型。

f2()
print(l)

----------------------------------------------------
x=0
def f1():
    # x=1
    def f2():
        # x=2
        def f3():
           # global x
           nonlocal x      //修改的是函数内部正上方的那个X,所有x被修改成2.只在函数内部有效。
           x=3
        f3()
        # print(x)
    f2()
    print(x)
f1()
print(x)

-----------------------------------------------------


优先掌握二:作用域关系,在函数定义时就已经固定
,与调用位置无关,在调用函数时,必须必须必须
回到函数原来定义的位置去找作用域关系

x=1
def  f1():
    def f2():
        print(x)
        return f2
def foo(func):
    x=300000
    func()
res=f1()
print(res)
func=f1()
print(func)
x=10000000
func()
x=10000000



def foo(func):
    x=300000000
    func() #f2()
x=10000000000000000000000



foo(f1())
# x=10000000000000000000000
# foo(f1())







x=1
def f1():
    global x
    x=2

f1()
print(x)
View Code
#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 内置模块的名字空间

三、global与nonlocal关键字  

global nonlocal掌握    :global 修改全局的
x=1
def f1():
    global x       明确声明x就是全局的x ,所以就会把全局的x=1,改成局部的x=2。
    x=2

f1()
print(x)
-----------------------------------------------

l=[]
def f2():
    l.append('f2')    能直接把l的值改‘f2’,因为l是列表,列表是可变类型。

f2()
print(l)

----------------------------------------------------
x=0
def f1():
    # x=1
    def f2():
        # x=2
        def f3():
           # global x
           nonlocal x      //修改的是函数内部正上方的那个X,所有x被修改成2.只在函数内部有效。
           x=3
        f3()
        # print(x)
    f2()
    print(x)
f1()
print(x)

四、闭包函数

 

 1、什么是闭包?

 

复制代码
#内部函数包含对外部作用域而非全局作用域的引用

#提示:之前我们都是通过参数将外部的值传给函数,闭包提供了另外一种思路,包起来喽,包起呦,包起来哇

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

        c=counter()
        print(c())
        print(c())
        print(c())
        print(c.__closure__[0].cell_contents) #查看闭包的元素
复制代码

 

2、闭包的意义与应用

 

复制代码
#闭包的意义:返回的函数对象,不仅仅是一个函数对象,在该函数外还包裹了一层作用域,这使得,该函数无论在何处调用,优先使用自己外层包裹的作用域
#应用领域:延迟计算(原来我们是传参,现在我们是包起来)
    from urllib.request import urlopen

    def index(url):
        def get():
            return urlopen(url).read()
        return get

    baidu=index('http://www.baidu.com')
    print(baidu().decode('utf-8'))
复制代码

 

大前提:作用域关系,在函数定义时就已经固定
,与调用位置无关,在调用函数时,必须必须必须
回到函数原来定义的位置去找作用域关系


闭包函数:
1. 定义在函数内部的函数
2. 包含对外部作用域名字的引用,而不是对全局作用域名字的引用
那么该内部函数就称为闭包函数
x=1
def  f1():
    x=11111111111
    def f2():
        print(x)
    return f2

func=f1()


x=1000
func()

def foo():
    x=12312312312312312312312312312312312313123
    func()


foo()


def deco():
    x=123123123123
    def wrapper():
        print(x)
    return wrapper

func=deco()


func()


#闭包函数的应用:惰性计算
import requests #pip3 install requests  安装pip3

def get(url):
    return requests.get(url).text

print(get('https://www.python.org'))
print(get('https://www.python.org'))
print(get('https://www.python.org'))
print(get('https://www.python.org'))

def index(url):
    # url='https://www.python.org'
    def get():
        # return requests.get(url).text
        print(requests.get(url).text)

    return get

python_web=index('https://www.python.org')
baidu_web=index('https://www.baidu.com')

python_web()
baidu_web()






name='egon'
def index(url):
    x=1
    y=2
    def wrapper():
        # x
        # y
        # return requests.get(url).text
        print(name)
    return wrapper

python_web=index('https://www.python.org')

# print(python_web.__closure__[0].cell_contents)
print(python_web.__closure__)
# print(python_web.__closure__[0].cell_contents)
# print(python_web.__closure__[1].cell_contents)
# print(python_web.__closure__[2].cell_contents)
View Code

五、嵌套函数

函数的嵌套调用:在调用一个函数的过程中,又调用了其他函数
def bar():
    print('from nbar')

def foo():                       #再调用一个函数的过程中,又去调用了另外一个函数
    print('from foo')
    bar()

foo()

-----------------------------------------
求两个值最大的函数
def max2(x,y):
    if x > y:
        return x
    else:
        return y


def max4(a,b,c,d):      求四个值的最大值
    res1=max2(a,b)      把a b 传进去会得到第一个结果
    res2=max2(res1,c)   再调用一次,拿着这一次得到的结果在跟c进行比较
    res3=max2(res2,d)
    return res3         得到res3最终的结果


print(max4(1,2,3,-1))

-------------------------------------------------
函数的嵌套定义:在一个函数的内部,又定义另外一个函数

def f2():
    print('from f2')

def f1():
    x=1                    函数内部定义的名字,只是在函数被调用的时候生效。
    # def f2()
    #     print('from f2')
    f2()

f1()

  

 

posted @ 2017-12-07 21:46  xiechao  阅读(303)  评论(0编辑  收藏  举报
levels of contents