• Python:命名空间(namespace)和作用域


    曾经学C++的时候,经常听到这个名词,它主要是为了避免命名冲突而产生的。

    就像有A(4个苹果),B(6个苹果)两个人,10个苹果,如果只标签了苹果,你无法判断哪个苹果是属于哪个人的,因为标签都是一样的;但是如果标签是A.苹果B.苹果,那么是不是很容易就知道了苹果是谁的了。

    • 命名空间:提供了一种从名称到对象的映射;主要是通过字典来实现的。

    在python中,函数、模块等都有自己的命名空间:

    局部命名空间(local namespace):即函数中定义的名称 —— 包括函数中的变量、参数、局部变量等;

    全局命名空间(global namespace):即模块中定义的名称 —— 包括模块中的变量、函数、类、参数、常量、导入(import)的模块等;

    内置命名空间(built-in namespace):即python内置的名称 —— 包括各种内置函数、Exception等;

    而,当python需要使用变量时,会在上述命名空间中依次查找,顺序是:

    局部命名空间,全局命名空间、内置命名空间

    同一命名空间中不能有重名,但不同命名空间可以。

    • 可以通过locals()、globals() 函数来获取命名空间的值(字典),在程序的不同位置执行结果不一定一致,因为结果是针对当前位置来说的。
    locals()
    
    globals()

    可以通过字典形式获取其中的值:

    • 作用域:可以理解为变量所起作用的范围,超出范围则某变量不能被使用。在python 程序中,直接访问一个变量,会从内到外依次访问所有的作用域直到找到,否则报错。Python 中只有模块(module),类(class)以及函数(def、lambda)才会产生新的作用域,其它的代码块(如 if/elif/else/、try/except、for/while等)是不会产生新的作用域的。

    作用域可以分为四种:

    Local:最内层,包含局部变量,一般指的是函数内部的作用域;

    Enclosing:包含非局部但是也不是全局的变量,主要是嵌套时,外层函数的变量,那么相对内层函数来说,嵌套的外层函数中的变量既不是局部变量也不是全局变量。

    Global:全局变量,例如当前模块中的全局变量。

    Build-in:内置变量。

    查找顺序一般是:Local--->Enclosing--->Global--->Build-in

    def test1():
        x1 = 1       #Enclosing 作用域
        def test2():
            x2 = 1   #Local 作用域
            print('x2=',x2)
            x1 = 100  #很明显,外层作用域中的x1没有受到影响,因为这里的x1属于Local
            
        test2()
        return x1
    
    aa = test1()
    print('aa=',aa)

    要想修改外层作用域(上层)的变量,需要用到global和nonlocal关键字。(注意,修改和访问不是一样的程度)

    def test1():
        x1 = 1       #Enclosing 作用域
        def test2():
            x2 = 1   #Local 作用域
            print('x2=',x2)
            
            nonlocal x1
            x1 = 100  #通过nonlocal,将这里的x1作用域变化为Enclosing作用域,即影响到Enclosing作用域中的x1的值
            
        test2()
        return x1
    
    aa = test1()
    print('aa=',aa)

    def test1():
        x1 = 1       # 这个x1属于Enclosing 作用域
        def test2():
            x2 = 1   #Local 作用域
            print('x2=',x2)
            
            global x1   # 这个x1属于全局作用域
            x1 = 100  #这里影响的是全局作用域中的x1值,并不会影响到Enclosing作用域中的值
            
        test2()
        return x1   #返回的是当前作用域Enclosing中的x1的值
    
    aa = test1()
    print('aa=',aa)
    
    print('x1=',x1)

    • 全局变量和局部变量

    定义在函数内部的变量,拥有局部作用域,属于局部变量。

    定义在函数外部的变量,拥有全局作用域,属于全局变量。

    全局变量可以在整个全局作用域内访问,但是要修改的话,需要用到global关键字。

    更细节一点,若涉及到class

    全局变量:一般在模块内、在所有函数外面、在class外面的变量。
    局部变量:一般在函数内、在class的方法内(未加self修饰)的变量。

    #

    参考:

    https://www.runoob.com/python3/python3-namespace-scope.html

    https://www.runoob.com/python/python-modules.html

    https://blog.csdn.net/alxe_made/article/details/80497151

  • 相关阅读:
    css边框以及其他常用样式
    jemeter学习-badboy录制与代理服务器录制
    linux基础命令学习
    cookie与session
    网址保存
    安全性测试要点转摘
    Charles弱网测试转载
    java 中文乱码以及转码
    spring学习总结——高级装配学习四(运行时:值注入、spring表达式)
    spring学习总结——高级装配学习三(Bean的作用域)
  • 原文地址:https://www.cnblogs.com/qi-yuan-008/p/12828515.html
Copyright © 2020-2023  润新知