009_做用域

1,做用域python

  • 全局做用域:做用域編寫的整個程序;
  • 局部做用域:做用域函數內部範圍;
  • 不一樣的局部做用域是獨立的,不一樣域的函數可使用相同的參數名。
  • 局部做用域能夠引用上級的局部做用域的變量,可是不能夠修改。
  • 在局部做用域,若是用了本域沒有的變量就會向上級查找。
  • 各自做用域的內的變量隨着各自域的釋放而釋放,即函數內的變量隨着函數的調用產生,隨着函數的結束釋放。
2,默認參數陷阱
  • 若是默認參數的值是一個可變數據類型,那麼每一次調用函數的時候,若是不賦值就公用這個數據類型的資源
def func(k = []):
    k.append(1)
    print(k)

func()      #>>>[1]
func([])    #>>>[1]
func()      #>>>[1,1]
func()      #>>>[1,1,1]
 
3,函數名與內置函數名同名時
    在正常狀況下,直接使用內置函數的名字,調用內置函數但當咱們在全局定義了和內置空間函數名相同時,會使用全局的名字
    遵循原則,當本身有的時候就不在找上級要若是本身沒有,就找上一級要,上級沒有在再找上上級,若是內置空間都沒有就報錯
def input():
    print('全局input')

input()     >>>全局input
4,函數名地址
def input():
    print('全局input')

def func():
    print(input)    #打印函數input()的地址

func()      #>>><function input at 0x0000023EBD04D378>
  •  func指向一個地址,地址加()時一個函數的執行
  •  func————>函數的內存地址
  •  函數名()————>函數的調用
  •  函數的內存地址()————>函數的調用
5,函數調用全局變量
  • 對於不可變數據類型 ,在局部能夠查看全局做用域中的變量,可是不能直接修改    
  • 若是想要在局部做用域修改全局變量,須要在程序的一開始添加global聲明    
  • 若是在一個局部(函數)做用域內聲明瞭一個global變量,那麼這個變量在局部的全部操做便是對全局變量的操做
a = 1
def func():
    print(a)        #局部能夠查看全局變量

func()      #>>>1
a = 1
def func2():
    a += 1          #報錯,局部不能更改全局變量
a = 1
def func3():
    global a        #聲明變量a是全局變量a,修改即修改的全局變量a
    a += 1

func3()
print(a)    #>>>2
a=3
def func2():
    a=0         #沒有特殊聲明,這是局部做用域func2函數範圍的變量a
    a += 1
    print(a)

func2()         #>>>1
print(a)        #>>>3
6,查看局部變量,全局變量
  • globals永遠打印全局做用域的
  • locals 意爲:本地的,打印locals所在位置的做用域
a = 1
b = 2
def func():
    x = '風'
    y = '雨'
    print(locals())   #查看局部變量  #>>>{'x': '風', 'y': '雨'}

func()
print(globals())      #查看全局變量  #輸出的結果日後看

print(globals())
print(locals())     #此時打印的都同樣,都是全局
7,函數的嵌套調用
#在一個函數裏調用另外一個函數
def thmax(x,y,z):
    c = max(x,y)
    return max(c,z)

print(thmax(2,3,4))     #>>>4

  

def outer():
    def inner():            #局部做用域定義了一個函數
        print('inner')      #在局部空間內的內容,在調用時加載,結束以後就會釋放(從內存空間刪除)
    inner()

outer()     #>>>inner

  

#對於變量空間,被包含的屬於下級,當本身須要東西時應向本身的上級索要
def outer():
    a = 1
    def inner():
        print(a)        #能夠查看outer()做用域下的a,inner()在outer()空間中,outer()是innter()的上級。
        print('inner')
    inner()

outer() #>>>1  inner
8,global的講解
  •   global表明的是聲明的變量是全局的變量,不能被其餘小局部同名變量改變
  • 對於打印,下級局部能夠查看上級變量,如本做用域沒有就會向上級做用域查找
a = 1    #全局變量a
def outer():
    a = 6   #outer()局部的變量a
    def inner():
        b = 2
        print(a)        #打印的是outer()局部做用域內的變量a
        print('inner')
        def inner2():
            global a  #聲明在inner2()局部做用域內的變量a是全局變量
            a += 1      #對全局變量a的操做
            print('inner2')
        inner2()
    inner()
    print(a)    #outer()做用域中的a

outer()
print('全局a:',a)
結果:       #注意:函數要先定義過才能執行,因此嵌套在一個函數內的新定義的函數
6            #須要包含新定義函數的這個函數執行的時候纔會被定義
inner
inner2
6
全局a: 2
9,nonlocal 只能用於局部變量,對全局無效
  • 對局部也只是對最後一層有影響
  • 做用:聲明本做用域中的這個變量是依次向上一級做用域找到的第一個同名的局部變量,在本做用域操做這個變量就是對依次向上一級做用域找到的第一個同名的局部變量的操做
10,函數名的講解
#函數名能夠賦值

def func():
    print(123)

func2 = func    #函數名能夠賦值
func2()         #>>>123

#函數名能夠做爲容器類型的元素

lis = [func,func2]
print(lis)
for i in lis:
    i()

#函數名能夠做爲函數的參數

def wer(f):
    f()

wer(func)

#函數名能夠做爲函數的返回值

def dnf(u):
    u()
    return u

re = dnf(func)
re()
11,閉包
    11.1,嵌套函數,內部函數調用外部函數的變量
    11.2,閉包的做用:日常的函數在調用時每次都要給變量開闢空間,釋放變量。所以,對於須要頻繁調用的函數來講浪費時間,下降了效率。
          因此,在閉包中,在執行後,閉包外部函數的變量就會一隻存在,直到程序的結束。經過將閉包內部函名返回出來,以便在全局做用域直接調用。
def outer():
    a = 1
    def inner():
        print(a)
    print(inner.__closure__)     #查看是不是閉包,是閉包會顯示cell
outer()

 如上程序雖然是閉包,但不能夠這樣寫,由於inner()就不會被調用。
web

    11.3,閉包的簡單使用
def outer():
    a = 1
    def inner():
        print(a)
    inner()
outer()
    11.4,閉包的經常使用方式
def outer():
    a =1
    def inner():
        print(a)
    return inner

inn = outer()
inn()
12,閉包實例,網頁代碼的讀取
    12.1,網頁代碼的讀取
from urllib.request import urlopen      #導入模塊中的一個方法
ret = urlopen('https://www.bilibili.com/').read()       #網址要有效(能打開)
print(ret)
    12.2,閉包的實例
from urllib.request import urlopen
def get_url():
    url = 'https://www.bilibili.com/'
    def get():
        ret = urlopen(url).read()
        print(ret)
    return get

web = get_url()
web()
相關文章
相關標籤/搜索