zoukankan      html  css  js  c++  java
  • 名称空间与作用域

    名称空间与作用域

    什么是名称空间?

    存放名字的空间

    如果你想访问一个变量值,必须先访问对应的名称空间,拿到名字和对应的地址的绑定关系

    名称空间的分类

    内置名称空间:

    伴随python解释器的启动/关闭而产生/回收,因而是第一个被加载的名称空间,用来存放一些内置的名字

    print(print)
    #输出结果为
    <built-in function print>   #built-in内建
    
    全局名称空间:

    伴随python文件的开始执行/执行完毕而产生/回收,是第二个被加载的名称空间,文件执行过程中产生的名字都会存放于该名称空间中

    x = 1
    def foo(x):
        if x ==1:
            print('苏喂苏喂')
        else:
            print('啦啦啦')
    
    
    foo(2)
    #输出结果为
    啦啦啦
    
    局部名称空间
    def foo(x):
        y=3 #调用函数时,才会执行函数代码,名字x和y都存放于该函数的局部名称空间中
    

    PS:名称空间的加载顺序是:内置名称空间->全局名称空间->局部名称空间,而查找一个名字,必须从三个名称空间之一找到,查找顺序为:局部名称空间->全局名称空间->内置名称空间。

    生命周期

    内置名称空间

    在python解释器启动时失效,关闭时失效

    全局名称空间

    当你启动当前py文件时失效,当前页面代码执行结束之后失效

    局部名称空间

    当你调用当前函数生效,函数体代码执行结束失效

    作用域

    全局作用域

    全局作用域:位于全局名称空间 内置名称空间中的名字属于全局范围,该范围内的名字全局存活(除非被删除,否则在整个文件执行过程中存活) 全局有效(在任意位置都可以使用)

    局部作用域

    局部作用域:位于局部名称空间中的名字属于局部范围。该范围内的名字临时存活(即在函数调用时临时生成,函数调用结束后就释放) 局部有效(只能在函数内使用)

    作用域于名字查找的优先级

    在局部作用域查找名字时,起始位置是局部作用域,所以先查找局部名称空间,没有找到,再去全局作用域查找:先查找全局名称空间,没有找到,再查找内置名称空间,最后都没有找到就会返回异常

    x = 100           #全局作用域
    def foo():
        x = 300       #局部作用域
        print(x)      #在局部找x
        
    
    foo()
    #结果为
    300                #先在局部作用域查找名字x,找到后直接返回,不再去找下一个
    

    在全局作用域查找名字时,起始位置便是全局作用域,所以先查找全局名称空间,没有找到,再查找内置名称空间,最后都没有找到就会抛出异常

    x = 100
    def foo():
        x = 300     #在函数调用时产生局部作用域的名字x,只在局部生效,不影响全局
    
    
    foo()
    print(x)       #在全局找x,结果100 
    

    PS: 可以调用内建函数locals()和globals()来分别查看局部作用域和全局作用域的名字,查看的结果都是字典格式。在全局作用域查看到的locals()的结果等于globals()

    函数的嵌套

    Python支持函数的嵌套定义,在内嵌的函数内查找名字时,会优先查找自己局部作用域的名字,然后由内而外一层层查找外部嵌套函数定义的作用域,没有找到,则查找全局作用域

    x = 1
    def outer():
        x = 2
        def inner():
            x = 3
            print('inner x:%s' %x)
    
    
        inner()
        print('outer x:%s' %x)
    
    outer()
    #结果为
    inner x:3
    outer x:2
    

    在函数内,无论嵌套多少层,都可以查看到全局作用域的名字,若要在函数内修改全局名称空间中名字的值,当值为不可变类型时,则需要用到global关键字

    x = 1
    def foo():
        global x  #声明x为全局名称空间的名字
        x = 2
    
    
    foo()
    print(x)
    #结果为
    2
    

    当实参的值为可变类型时,函数体内对该值的修改将直接反应到原值

    num_list = [1, 2, 3]
    def foo(num):
        num.append(5)
    
    
    foo(num_list)
    print(num_list)
    #结果为
    [1, 2, 3, 5]
    

    对于嵌套多层的函数,使用nonlocal关键字可以将名字声明为来自外部嵌套函数定义的作用域(非全局)

    def f1():
        x = 2
        def f2():
            nonlocal x
            x = 3
        f2()
        print(x)
    f1()
    #结果为
    3
    
    

    函数对象

    函数可以被引用
    def sum(x, y):
        z = x + y
        print(z)
    func = sum
    print(func(1,2))
    #结果为
    3
    None
    
    
    函数可以作为容器类型的元素
    
    
    函数可以作为参数传入另外一个函数
    函数的返回值可以是一个函数

    1.函数对象
    - 是什么?
    函数的名字就是函数对象,函数名指向的是函数的内存地址。

        - 有什么用?
            - 可以被引用
            - 可以被当做参数传入
            - 可以被当做函数的返回值
            - 可以当做参数传入容器中
                {"key": func--X0...}
    
        - 函数对象的应用:
            补充--》可以优雅地取代if分支
    
    2.函数嵌套
        - 函数嵌套定义: 让内层函数封闭起来,不让外部直接调用。
            def func1():
    
                def func2():
                    pass
    
                return func2
    
            func2()
    
    
    
        - 函数嵌套调用: 将复杂并且小的功能,在函数内部调用,解决代码结构清晰问题。
            def login():
                pass
    
            def register():
                pass
    
            # 使用func函数的前提是,必须先注册,登录,再使用
            def func():
                register()
                login()
                func的逻辑代码
                ...
    
    3.名称空间与作用域
        - 名称空间什么是?
            用来存放名字的,名称空间是一个在内存中的空间。
            x = 100
            def func():
                pass
            - 内置名称空间:
                在python解释器启动时产生,关闭时销毁。
    
            - 全局名称空间:
                执行当前的py文件时产生,文件执行结束后销毁,关闭解释器时彻底销毁。
    
            - 局部名称空间:
                在执行函数时产生,临时存活,函数调用结束时销毁。
    
            - 名称空间 加载顺序与查找顺序:
                - 加载顺序:内置 ---> 全局 ---> 局部
                - 查找顺序: 局部 ---> 全局 ---> 内置
    
        - 作用域: 名称空间作用的范围
            - 全局:
                内置名称空间 + 全局名称空间
                - 只要程序一直执行,永久存活,若程序结束,则销毁
    
            - 局部:
                局部的名称空间 + 局部的局部的名称空间
                - 只要程序一直执行,调用函数时存活,结束时销毁
    

    今日内容

  • 相关阅读:
    Redis之分布式锁的使用
    Redis之lua脚本
    Redis 集群的水平扩缩容
    Redis集群搭建及原理
    Redis 的主从、哨兵架构
    CompletableFuture 使用介绍
    Spring Boot 2.x使用H2数据
    pom.xml
    nexus-staging-maven-plugin 踩坑
    安卓Hook折腾研究的笔记记录
  • 原文地址:https://www.cnblogs.com/a736659557/p/11892354.html
Copyright © 2011-2022 走看看