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

    一 名称空间

    1、名称空间namespace

    名称空间是存放名字(变量名与内存地址的绑定关系)的地方,是对栈区的划分,有了名称空间之后,就可以在栈区中存放相同的名字。

    (栈区划分成多片名称空间,相当于把名字归类了,最大的好处是:当两个变量名相同时,可以存放在两个不同的名称空间,就不会冲突了)

    名称空间分为三种:

    ​ 内置名称空间、全局名称空间、局部名称空间(多个)

    名字----------------》相当于人

    栈区-----------------》地球

    名称空间-----------》国家

    作用域--------------》国家的影响力

    名称空间与作用域介绍

    Ps:名称空间只有优先级之分,本身并无嵌套关系

    1.1 内置名称空间

    ​ 存放的名字:存放的是 python 解释器内置的名字

    >>> print
    <built-in function print>
    >>> input
    <built-in function input>
    

    ​ 存活周期:python 解释器启动则产生、python 解释器关闭则销毁

    1.2 全局名称空间

    ​ 存放的名字:只要不是函数内定义,也不是内置的,剩下的都是全局名称空间的名字。

    ​ 存活周期:python 文件执行则产生,python文件运行完毕后则销毁

    import os  #全局名称空间名字
    
    x= 10    #全局名称空间名字
    if 13 > 3:   
    		y =20  #全局名称空间名字
    		if 3==3:
    			 z=30 #全局名称空间名字
    
    #func = 函数的内存地址(函数名是全局名称空间的名字)
    def func():
    		a = 111
        b = 222
    
    func()
    

    1.3 局部名称空间

    存放的名字:在调用函数时,运行函数体代码过程中产生的函数内的名字

    存活周期:在调用函数时存活,函数调用完毕后则销毁

    def func(a,b):
    		pass
    		
    func(10, 1)
    

    注:同一个函数,被调用多次,就会产生多个局部名称空间(哪怕没有函数体代码)

    func(11, 12)
    func(13, 14)
    func(15, 16)
    

    1.4 名称空间的加载顺序

    内置名称空间 > 全局名称空间 > 局部名称空间

    1.5 名称空间的销毁顺序

    局部名称空间 > 全局名称空间 > 局部名称空间

    1.6 名字的查找优先级

    大前提:当前所在的位置(先找当前空间)向上一层一层查找

    ​ 内置名称空间

    ​ 全局名称空间

    ​ 局部名称空间

    如果当前在局部名称空间:

    ​ 局部名称空间---->全局名称空间----->内置名称空间

    如果当前在全局名称空间

    ​ 全局名称空间 ---->内置名称空间

    示例:

    input=333
    def func():
        input=444
        print('===>', input) #===> 444
    
    func()
    print(input) # 333
    

    名称空间的'嵌套'关系是以函数定义阶段为准,与调用位置无关****(很重要)

    即函数的嵌套关系与名字的查找顺序是在定义阶段就已经确定好的

    x = 1
    def func():
      	print(x) #1
    def foo():
      	x =222
        func()
        
    foo()
    

    函数嵌套定义

    input =111
    def f1():
      	def f2():
            #input = 333
            print(input) #222
        input = 222
       	f2()
        
    f1()
    

    示范 4:

    x = 111
    def func():
      	print(x) #报错,x=222 在 print(x)下面
        x=222
    func()
    

    例题:

    input=333
    def func():
        input=444
    func() 
    print(input) #333
    

    image-20200320181148997

    def func():
        print(x)
    x=111
    
    func() #111
    

    image-20200320181219323

    x=1
    def func():
       print(x) #1
    
    def foo():
        x=222
        func()
    x= 333
    foo()
    

    image-20200320181249127

    x=111
    
    def foo():
        print(x,) #111
    
    def bar():
        print(x)  #111
    
    foo()
    bar()
    
    x=1
    def func2():
      	print(x) #3
        func1()
    
    x=2
    def func1():
        print(x) #3
    
    x=3
    
    func2()
    
    a1 = 1
    def func():
        a1=3
        print(a1) #3
        a1=4
    a1 = 2
    func()
    

    二 作用域

    作用域---->作用范围

    按照名作用范围的不同,可以将三个名称空间划分为两个区域:

    ​ 全局作用域和局部作用域

    全局作用域:内置名称空间 、全局名称空间

    ​ 1、全局存活

    ​ 2、全局有效:被所有函数共享

    x = 111
    def foo():
      	print(x,id(x))
    def bar():
      	print(x, id(x))
        
    foo()
    bar()
    

    局部作用域:局部名称空间的名字

    1、临时 存活

    2、局部有效:函数内有效

    def foo():
    		def f1():
    				def f2():
    						print(x)
    
    LEGB
    # builtin
    # global
    def f1():
        # enclosing
        def f2():
            # enclosing
            def f3():
                # local
                pass
    

    三 global 与 nonlocal

    global

    示范 1:

    x =111
    def func():
        x=222
    
    func()
    print(x) #111
    

    如果在局部内想要修改全局的名字对应的值(不可变类型),需要global

    x = 111
    def func():
      	global x #声明 x 这个名字是全局的名字,不要再造新的名字了
        x =222
    
    func()
    print(x) #222
    

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

    num_list = [1,2,3]
    def foo(nums):
    		nums.append(5)
    
    foo(num_list)
    print(num_list) #[1,2,3,5]
    
    

    nonlocal(了解)

    对于嵌套多层的函数,使用 nonlocal 关键字可修改函数的外层函数包含的名字对应的值(不可变类型)。

    注意,这里只能修改包含名字的最近一层的外层函数对应的值

    x = 0
    def f1():
        x = 11
        def f2():
            x = 222
            def f3():
                nonlocal x
                x = 333
            f3()
            print('f2内的 x:', x) #f2内的 x: 333
    
        print('f1内的 x:', x)  # f1内的 x: 11
        f2()
    
    f1()
    结果展示:
    f1内的 x: 11
    f2内的 x: 333
    
  • 相关阅读:
    OpenCV特征描述
    OpenCV特征点检测
    expect实现无交互操作
    文件的修改时间
    sshd登录攻击
    tcp三次握手和syn 洪水攻击
    vim使用
    PHP拓展开发
    【转】LINUX 手动建立SWAP文件及删除
    Ubuntu下crontab命令的用法
  • 原文地址:https://www.cnblogs.com/xy-han/p/12526559.html
Copyright © 2011-2022 走看看