zoukankan      html  css  js  c++  java
  • day-4 名称空间 作用域 函数嵌套 函数名 闭包 装饰器

    1.1名称空间的分类

    名称空间的定义:存放名字与值的关系的空间起了一个名字

     

    名称空间分为三种:

      全局命名空间

      局部命名空间

          内置命名空间

    A.全局名称空间

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

    B.局部名称空间

    在函数的运行中开辟的临时的空间

     

    C.内置名称空间

    存放了python解释器为我们提供的名input,print,str,list,tuple...它们都是我们熟悉的,拿过来就可以用的方法。

     

    1.2名称空间的一些规则

    当程序运行时,代码从上至下一次执行,会将变量与值的关系存储在一个空间中,这个空间叫做名称空间,命名空间,全局名称空间。

    当程序遇到函数时,他会将函数名存在内存中,函数体莫不关心。

    当函数执行时,内存会临时开辟一个空间,存放函数体里面的代码(变量,代码等),函数外面访问不到临时空间的内容,随着函数的执行完毕,临时名称空间会释放掉,向这个临时开辟的空间叫临时名名称空间,也叫局部名称空间。

    1.3作用域

    作用域就是作用范围,按照生效范围可以分为全局作用域和局部作用域。

    1.3.1全局作用域:包含内置名称空间、全局名称空间,在整个文件的任意位置都能被引用、全局有效

    1.3.2局部作用域:局部名称空间,只能在局部范围内生效

    1.4加载顺序

    内置命名空间(程序运行前加载,也就是解释器运行的时候)->全局命名空间(程序运行中:从上到下加载)->局部命名空间(程序运行中:函数调用时才加载)

    1.5取值范围

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

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

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

    2.1内置函数 globals() locals()

       globals()返回字典,字典里面的内容是全局作用域

       locals()返回字典,当前位置的所有变量

    2.1.1全局范围运行globals() locals()

    name='alex'

    age=1000

    def func1():

        name1='oldboys'

        age=10

        # print(locals())

    func1()

    print(globals())

    print(locals())

    #此时打印的内容是一样的,其实都是全局的变量

    # '__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x0000000001EBA3C8>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'E:/d22-01/day-4/练习.py', '__cached__': None, 'name': 'alex', 'age': 1000, 'func1': <function func1 at 0x0000000001E13E18>}

    2.1.1局部范围运行locals()

    name='alex'

    age=1000

    def func1():

        name1='oldboys'

        age=10

    print(locals())

    # {'age': 10, 'name1': 'oldboys'}

    func1()

    print(globals())

    # '__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x0000000001EBA3C8>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'E:/d22-01/day-4/练习.py', '__cached__': None, 'name': 'alex', 'age': 1000, 'func1': <function func1 at 0x0000000001E13E18>}

    3.1关键字global and nonlocal

    3.1.2

    3.1.2.1 global:

     1,声明一个全局变量。

     2,在局部作用域想要对全局作用域的全局变量进行修改时,需要用到 global(限于字符串,数字,布尔值)。

      3,对可变数据类型(list,dict,set)可以直接引用不用通过global。

    3.1.2.2 对于第2点的举例:

    A.可引用并修改全局变量

    count = 1

    def func1():

        global count

        count=count+1

        print(count)

    func1()#count为2

    B.在局部声明全局变量

    def func1():

        global name

         name='alex'

    func1()

    print(name)#alex

    3.1.2.3 对于第3点的举例:

    l1=[1,2,3]

    def func1():

        l1.append(4)

        print(l1)

    func1()#[1, 2, 3, 4]

    l1.append(5)

    print(l1)# [1, 2, 3, 4, 5]

    3.1.1

    nonlocal:  1,不能修改全局变量。

    2,在局部作用域中,对父级作用域(或者更外层作用域非全局作用域)的变量进行引用和修改,并且引用的哪层,从那层及以下此变量全部发生改变。

    def add_b():

        b = 42

        def do_global():

            b = 10

            print(b)#10

            def dd_nonlocal():

                nonlocal b

                b = b + 20

                print(b)#30

            dd_nonlocal()

            print(b)#30

        do_global()

        print(b)#42

    add_b()

    运行结果:

    10

    30

    30

    42

    3.2取值的定义及规则

    取值:引用而不是改变

    取值是从小到大LEGB,想改变上层空间的变量,要用到global或者nonlocal

    4.函数的嵌套和作用域

    4.1函数的嵌套一:在一个函数调用全局定义的函数

    def max2(x,y):

        m  = x if x>y else y

        return m

    def max4(a,b,c,d):

        res1 = max2(a,b)

        res2 = max2(res1,c)

        res3 = max2(res2,d)

        return res3

    result=max4(23,-7,31,11)

    print(result)#31

    4.2函数的嵌套二:在函数里定义函数并调用函数

    1.

    def f1():

        print("in f1")

        def f2():

            print("in f2")

        f2()

    f1()

    #输出结果

    in f1

    in f2

    2.

    def f1():

        def f2():

            def f3():

                print("in f3")

            print("in f2")

            f3()

        print("in f1")

        f2()

    f1()

    #输出的结果

    in f1

    in f2

    in f3

    4.3函数的作用域

    小范围作用域可以使用大范围的变量,但是反之不行,他是单向的。

    4.3.1例子1:

    def f1():

        a = 1

        def f2():

            def f3():

                print(a)

            f3()

        f2()

    f1()

    #输出结果为1

    例子2:

    def f1():

        a = 1

        def f2():

            a = 2

            print('a in f2:',a)

        f2()

        print('a in f1:',a)

    f1()

    #输出结果:

    a in f2: 2

    a in f1: 1

    5.函数名

    5.1可被引用

    def func():

        print('in func')

    f = func

    print(f)# <function func at 0x00000000003B3E18>

    5.2可作为容器元素

    def func1():

        print(111)

    def func2():

        print(222)

    def func3():

        print(333)

    l1=[func1,func2,func3]

    for i in l1:

    i()

    5.3函数名可作为参数传递

    def func1():

        print(111)

    def func2(x):

        x()

        print(222)

    func2(func1)

    5.4函数名可以作为返回值

    def func1():

        print(111)

    def func2():

        print(222)

        return func1

    ret=func2()()

    5.5函数名可作为变量赋值

    def func1():

        print(111)

        return 111

    f1=func1

    f2=f1

    f3=f2

    f3()

    print(f3)

    5.6 第一类对象(first-class object)

    1.可在运行期创建

    2.可用作函数参数或返回值

    3.可存入变量的实体。

    6.闭包函数

    内存函数对外层函数非全局变量的引用。

    作用:用于装饰器和网络爬虫

    6.1例子

    def func():

        name = 'eva'

        def inner():

            print(name)

        return inner

    f = func()

    f()#输出eva

    6.2判断闭包函数的方法__closure__

    #输出的__closure__有cell元素 :是闭包函数

    def func():

        name = 'eva'

        def inner():

            print(name)

        print(inner.__closure__)

        return inner

    f = func()

    f()

    #(<cell at 0x00000000027B65B8: str object at 0x00000000028382D0>,)

    #eva

    #输出的__closure__为None :不是闭包函数

    name = 'egon'

    def func2():

        def inner():

            print(name)

        print(inner.__closure__)

        return inner

    f2 = func2()

    f2()

    #None

    #egon

    7.装饰器

    装饰器本质上就是一个python函数,他可以让其他函数在不需要做任何代码变动的前提下,增加额外的功能,装饰器的返回值也是一个函数对象。

    装饰器的应用场景:比如插入日志,性能测试,事务处理,缓存等等场景。

    装饰器 本质就是闭包

    7.1 装饰器的固定格式

    def wrapper (func):

        def inner(*args,**kwargs):

            '''执行函数之前要做的'''

            re = func(*args,**kwargs)

            '''执行函数之后要做的'''

            return re

    return inner

    7.2装饰器的应用

    装饰器的应用在被装饰的函数前面

    @wrapper

    def essay():

        print ('欢迎用户{}进入文章页面'.format (status_dict['username']))

  • 相关阅读:
    字符串转换相关
    Xcode新功能
    CocoaPods使用详情及版本未更新安装报错
    Cannot create __weak reference in file using manual refs Xcode 7.3
    UIButton实现左文字右图片
    iOS App 上架流程-版本更新注意事项
    iOS App 上架流程-新版本1.0上架
    NSNotification的用法
    NScfBool转bool类型
    百度地图 移动坐标显示该坐标周围对应的信息
  • 原文地址:https://www.cnblogs.com/junyingwang/p/9120322.html
Copyright © 2011-2022 走看看