zoukankan      html  css  js  c++  java
  • Python语法(高级语法)- 命名空间和作用域

    Python语法(高级语法)- 命名空间和作用域
     
    命名空间(Namespace)
    • 命名空间是从名称到对象的映射,大部分的命名空间都是通过 Python 字典来实现的。
    • 命名空间提供了在项目中避免名字冲突的一种方法。各个命名空间是独立的,对象在同一个命名空间中不能有重名,但不同的命名空间可以重名。
     
     

    命名空间的类型
    • 内置名称(built-in names)
      • 比如函数名 abs、char 和异常名称 BaseException、Exception 等等。
      • 可以通过下面的方法查看内置名称:
    >>> import builtins
    >>> dir(builtins)
      • 全局名称(global names)
        • 模块中定义的名称,包括函数、类、其它导入的模块、模块级的变量和常量。
      • 局部名称(local names)
        • 类中定义的名称,包括数据属性,方法属性。
        • 函数中定义的名称,包括函数的参数、局部定义的变量。
     

    命名空间的查找顺序
    • 局部的命名空间去 -> 全局命名空间 -> 内置命名空间
     
     
    命名空间的生命周期
    • 取决于对象的作用域,如果对象执行完成,则该命名空间的生命周期就结束。
     

     
    对象的作用域
    • 作用域就是一个Python程序可以直接访问命名空间的正文区域。
    • 在一个python程序中,直接访问一个变量,会从内到外依次访问所有的作用域直到找到,否则会报未定义的错误。
    • Python中,程序的变量并不是在哪个位置都可以访问的,访问权限决定于这个变量是在哪里赋值的。变量的作用域决定了在哪一部分程序可以访问哪个特定的变量名称。
    • 只有模块(module)、类以及函数(def、lambda)才会引入新的作用域,其它的代码块(如 if/elif/else/、try/except、for/while等)是不会引入新的作用域的。
    var_f0 = 789
    while (var_f0 == 789):
        print("change var_f0......")
        var_f0 = 123123  # 在while中更新var_f0的值
     
    print(var_f0)
     
    输出:
    change var_f0......
    123123
     
     

    作用域的类型
    • L(Local):最内层,包含局部变量。
      • 比如一个函数/方法内部。
    • E(Enclosing):包含了非局部(non-local)也非全局(non-global)的变量。
      • 比如两个嵌套函数,一个函数(或类) A 里面又包含了一个函数 B ,那么对于 B 中的名称来说 A 中的作用域就为 nonlocal。
     
    • G(Global):当前脚本的最外层。
      • 比如当前模块的全局变量。
    • B(Built-in): 包含了内建的变量/关键字等。最后被搜索
     

    作用域的查找顺序
    • L –> E –> G –> B
     
     

     
    全局变量和局部变量
    • 全局变量:定义在函数外的变量具有全局作用域。
      • 变量定义在模块的函数外,则在模块内具有全局作用域。
      • 变量定义在类内的函数外,则在类内具有全局作用域。
     
    • 局部变量:定义在函数内的变量具有函数内的局部作用域。
     
    global 和 nonlocal关键字
    • 当内部作用域想修改外部作用域的变量时,需要用到global和nonlocal关键字。
     
    用例1:在局部作用域中没有同名变量时,可以访问外部变量
    # 全局变量,作用域:整个模块。
    var_f0 = 123
     
    def func1():
        # 局部变量,作用域:func1
        var_f1 = 456
     
        def func2():
            print("in func2 start......")
            print("var_f0:", var_f0)  # 在func2中可以访问外部变量
            print("var_f1:", var_f1)  # 在func2中可以访问外部变量
            print("in func2 end......")
     
        print("before func2: ")
        print("var_f0:", var_f0)
        print("var_f1:", var_f1)
        func2()
        print("after func2: ")
        print("var_f0:", var_f0)
        print("var_f1:", var_f1)
     
     
    func1()
     
    输出:
    before func2:
    var_f0: 123
    var_f1: 456
    in func2 start......
    var_f0: 123
    var_f1: 456
    in func2 end......
    after func2:
    var_f0: 123
    var_f1: 456
     
    用例2:在局部作用域中不能直接修正外部变量
    # 全局变量,作用域:整个模块。
    var_f0 = 123
     
    def func1():
        # 局部变量,作用域:func1
        var_f1 = 456
     
        def func2():
            print("in func2 start......")
            print("var_f0:", var_f0)  # 在func2中不可以访问
            print("var_f1:", var_f1)  # 在func2中不可以访问
     
     
            var_f0 = 789 # 这并不是在给模块变量var_f0赋值,而是在内部重新定义了同名变量,导致print("var_f0:", var_f0)出错。
            var_f1 = 789 # 这并不是在给模块变量var_f1赋值,而是在内部重新定义了同名变量,导致print("var_f1:", var_f1)出错。
            print("in func2 end......")
     
     
        print("before func2: ")
        print("var_f0:", var_f0)
        print("var_f1:", var_f1)
        func2()
        print("after func2: ")
        print("var_f0:", var_f0)
        print("var_f1:", var_f1)
     
     
    func1()
     
    输出:
    before func2:
    var_f0: 123
    var_f1: 456
    in func2 start......
    var_f0: 123
    Traceback (most recent call last):
      File "U:/Project/Python_Training/Pytho_Basic/zz_test.py", line 29, in <module>
        func1()
      File "U:/Project/Python_Training/Pytho_Basic/zz_test.py", line 24, in func1
        func2()
      File "U:/Project/Python_Training/Pytho_Basic/zz_test.py", line 15, in func2
        print("var_f1:", var_f1)  # 在func2中可以访问
    UnboundLocalError: local variable 'var_f1' referenced before assignment
     
    用例3:在局部作用域中修正外部变量的方法用例1:在局部作用域中没有同名变量时,可以访问外部变量
    # 全局变量,作用域:整个模块。
    var_f0 = 123
     
    def func1():
        # 局部变量,作用域:func1
        var_f1 = 456
     
        def func2():
            global var_f0   # 声明改变量为外部变量
            nonlocal var_f1 # 声明改变量为外部变量
     
            print("in func2 start......")
            print("var_f0:", var_f0)  # 在func2中可以访问
            print("var_f1:", var_f1)  # 在func2中可以访问
     
            var_f0 = 789 # 在func2中修正
            var_f1 = 789 # 在func2中修正
            print("in func2 end......")
     
        print("before func2: ")
        print("var_f0:", var_f0)
        print("var_f1:", var_f1)
        func2()
        print("after func2: ")
        print("var_f0:", var_f0)
        print("var_f1:", var_f1)
     
    func1()
     
    输出:
    before func2:
    var_f0: 123
    var_f1: 456
    in func2 start......
    var_f0: 123
    var_f1: 456
    in func2 end......
    after func2:
    var_f0: 789
    var_f1: 789
     
     
     
     
     
     
     
     
     
     
     
     
     
     
  • 相关阅读:
    Linux命令总结--grep命令
    Linux命令总结--sed命令
    python函数--enumerate()方法
    python函数--index()方法
    在objc项目中使用常量的最佳实践
    iOS 开发 初级:应用内购买 In-App Purchase
    CFUUIDRef和CFStringRef-生成唯一标识符
    保留你的dSYM文件
    xcode 环境,多工程联编设置【转】
    ld: symbol dyld_stub_binding_helper not found, normally in crt1.o/dylib1.o/bundle1.o for architecture i386
  • 原文地址:https://www.cnblogs.com/JacquelineQA/p/13835667.html
Copyright © 2011-2022 走看看