python名稱空間與做用域

名稱空間與做用域

函數內部的函數只能在函數的內部調用,不能在函數的外部調用。app

def f1():
    x=1
    print('from f1')
    def f2():
        print('from f2')
print(x)



#會進行報錯:
Traceback (most recent call last):
  File "F:/python學習/python自學/測試4.py", line 6, in <module>
    print(x)
NameError: name 'x' is not defined

Process finished with exit code 1

1、名稱空間

名稱空間:在學習內存管理的時候,變量的建立其實就是在 內存中開闢了一個新的空間,用來存儲變量,可是卻沒說過變量名的存儲,其實變量在內存中有一快內存存儲變量名與變量之間的綁定關係的空間,而這個空間稱爲名稱空間。函數

  1. 內置名稱空間:python解釋器獨有的。學習

    內置名稱空間:存放python解釋器自帶的名字,如,int,float,len等測試

    生命週期:Python解釋器啓動的時候python自動開闢內置名稱空間存放了這些python的內置方法,python解釋器中止解釋以後纔會銷燬#code

  2. 全局的名稱空間對象

    全局名稱空間:除了內置和局部的名字外,都存放在全局名稱空間,以下面代碼中的x,func生命週期

    生命週期:全局須要本身定義, python文件執行以後纔可能有全局名稱空間,文件結束以後纔會銷燬內存

    x = 1  #x 是全局變量
    def func():
        print(x)
    func()
  3. 局部名稱空間作用域

    局部名稱空間:用於存放函數調用期間函數體產生的名字,以下面的代碼的f2

    生命週期:在文件執行的時候函數調用期間時生效,在函數執行結束後失效。

    def f1():
        def f2():
            print('from f2')
        f2()
    
    f1()
    #輸出:
    from f2
  4. (執行)加載順序

    因爲.py文件是由Python解釋器打開的,所以必定是在Python解釋器中的內置名稱空間加載結束後,文件纔開始打開,這個時候纔會產生全局名稱空間,但文件內有某一個函數被調用的時候,纔會開始產生局部名稱空間,所以名稱空間的加載順序爲:

    內置名稱空間——>全局名稱空間——>局部名稱空間

  5. 查找順序

    因爲名稱空間是用來存放變量名與值之間的綁定關係的,因此但凡要查找名字,必定是從三者之一找到,查找順序爲:
    從當前的所在位置開始查找,若是當前所在的位置爲局部名稱空間,則查找順序爲:

    當前位置——>局部名稱空間——>全局名稱空間——>內置名稱空間

    x= 1
    y =2
    len =  100
    def func():
        y = 3
        len = 1000
        print(y)
        print(len)
    
    func()
    #輸出:
    3
    1000
    x = 1
    
    
    def func():
        print(x)
    
    
    x = 10
    func()
    
    #輸出:
    10

2、做用域

做用域: 產生做用的範圍,做用域關係僅適用不可變數據類型,不適用於可變數據類型

  1. 全局做用域

    全局做用域:全局有效,全局存活, 全局+內置名稱空間中的變量,全局做用域中的變量只能在全局中使用

    x = 1 # x爲全局名稱空間
    def func():
        print(x)
    func()
    #輸出:
    1
  2. 全局做用域

    局部做用域:局部有小,臨時存儲,只包含局部名稱空間。 局部名稱空間中的變量,局部做用域中的變量只能在局部中使用

def f1():
    def f2():
        def f3():
            print(x)

        x = 2
        f3()

    f2()


f1()
#輸出:
2
  1. 須要注意的是:做用域在函數定義階段就固定死了,與函數的調用無關。
x = 1


def f1():
    print(x)


def f2():
    x = 2
    f1()


f2()
#輸出:
1
  1. 函數對象與做用域的應用
def f1():
    def inner():
        print('from inner')

    return inner


f = f1() # 把局部定義的函數放在全局之中


def bar():
    f()


bar()
#輸出:
from inner

3、補充知識點

  1. qlobal關鍵字

    將局部變量修改成全局做用域中的變量。

    x = 1
    
    
    def f1():
        x = 2
    
        def f2():
            global x  #修改x爲全局變量
            x = 3
    
        f2()
    
    
    f1()
    print(x)
    # 輸出:
    3
    1. nonlocal關鍵字

      修改局部做用域的變量爲上一層局部做用域中的變量。

      x = 1
      
      
      def f1():
          x = 2
      
          def f2():
              nonlocal x
              x = 3
      
          f2()
          print(x)
      
      
      f1()
      #輸出:
      3
  2. 關鍵點

    1. 在局部想要修改全局的可變類型,不須要任何聲明,能夠直接修改。

    2. 在局部若是想要修改全局的不可變類型,須要藉助global聲明,聲明爲全局變量,既能夠直接修改。

      lis = list()
      
      
      def f1():
          lis.append(1)
      
      
      print(lis)
      f1()
      print(lis)
      
      #輸出:
      []
      [1]
相關文章
相關標籤/搜索