2019-07-10 函數的進階(一)

 

1、函數對象python

    函數是第一類對象:函數名指向的值能夠被當作參數傳遞函數

    1.函數名能夠被傳遞spa

def func():
    print('from func')
f = func      #函數名能夠被傳遞,這裏用一個變量名賦值
func()    #from func
print(f)    #這裏打印的是函數的內存地址
f()       #f()等價於  func()

    2.函數名能夠被當作參數傳遞給其餘函數code

def func():
    print('from func')

def index(args):
    print(args)      #等價於print(func)   打印函數func內存地址
    args()        #運行函數func()  執行內部代碼
    print('from index')
index(func)    #函數名func當作參數名傳遞到index函數中



#結果
#<function func at 0x0000001A50EE0E18>
#from func
#from index

    3.函數名能夠被當作函數的返回值對象

def index():
    print('index')
def func():
    print('func')
    return index
res = func()   #返回值是  index
print(res)   #打印函數名index的內存地址
res()    #調用運行index()函數


#結果
#func
#<function index at 0x0000001DB2490E18>
#index

    4.函數名能夠被當作容器類型的參數blog

def func():
    print('func')
print(func())     #func    None
l = [1,2,func,func()]  
print(l)



#結果
func
None
func      #爲何結果有這個,由於在l調用了函數func(),因此打印一個func
[1, 2, <function func at 0x0000009769AF0E18>, None]  

2、函數調用    (在一個函數內部調用其餘函數,能夠將複雜的邏輯簡單化)生命週期

def index():
    func()
    print('index')

def func():
    print('func')

index()


#調用index()以後,func()已經被定義了,能夠被調用

3、名稱空間內存

    名稱空間是什麼:就是存放變量名和變量值的內存地址的綁定關係的地方作用域

    名稱空間的分類:io

      1.內置空間名稱:python解釋器提早給你定義好的名字(已經存放在內置名稱空間了)

          就是一些內置函數:好比   len()/max()....

      2.全局名稱空間:文件級別的代碼

      3.局部名稱空間:函數體內建立的名字都屬於局部名稱空間  

def func():
    username = 'jason'    #這個username是局部名稱空間
    print(username)
func()

  總結:生命週期

    內置名稱空間:只要python解釋器已啓動立馬建立   關閉python解釋器的時候內置名稱空間自動銷燬(針對於python解釋器)

    全局名稱空間:只要你運行py文件的時候會自動建立   py文件程序運行結束自動銷燬 (針對於py文件)

    局部名稱空間:函數被調用的時候建立  函數結束就銷燬(針對於函數的調用開始結束)

 

4、名稱空間的查找順序

  注意:先要肯定好你當前在哪(在哪一個空間)

      查找順序    

      1.若是你如今在全局:   全局  >>>內置   (先從全局找再到內置)

      2.若是你如今在局部:局部>>全局>>內置(先從局部找再到全局再到內置)

  例題:

  局部命名空間:先定位要打印的len屬於什麼空間,由於它是在函數裏面的變量,因此它是局部名稱空間,先找局部變量,正好函數裏面有一個變量名賦值,因此這個len就從這取值

len = '我是全局名稱空間的len'
def func():
    len = '我是局部名稱空間的len'
    print(len)
func()

 

  全局和局部:咱們先來看紅色的len,這個len在全局的位置,查找順序先從全局開始,不會找到函數內部的局部。在全局裏面已經有一個定義的len,因此用這個  '我是全局名稱空間的len'。而後函數裏面的len就和上面的同樣了。

len = '我是全局名稱空間的len'
def func():
    len = '我是局部名稱空間的len'
    print(len)
print(len)  # 我如今站在的是全局的位置
func()

#結果
#我是全局名稱空間的len
#我是局部名稱空間的len

  局部:打印的x在局部位置,在自己函數沒有,因此就往上一個找局部,找到有一個x。

def func():
    x = 1
    def index():
        print(x)  # 1
    return index

res = func()
x = 999
res()

  全局:若是把上一道題的局部x刪掉,就要到全局裏面找,找到x=999在函數調用以前已經定義了,最後結果就是999

def func():
    def index():
        print(x)  # 999
    return index

res = func()
x = 999
res()

  全局:x定位到局部,可是在inner裏面找不到,outer裏面也找不到,因此x是使用全局,後面的inner在哪裏調用,x都是在全局找值

x=111
def outer():
    def inner():
        print('from inner',x)     #from inner 111
    return inner
f=outer()
def func():
    x=333
    f()
func()

  總結:函數在定義階段就已經固定查找名字的順序了,不會由於函數調用的位置改變而改變

5、做用域

  做用域就是做用範圍,按照生效範圍能夠分爲全局做用域和局部做用域

  全局做用域:包含內置名稱空間、全局名稱空間,在整個文件的任意位置都能被引用,全局有效

  局部做用域:局部名稱空間、只能在局部範圍生效

  

  global和nonlocal

    global:在局部修改全局的不可變數據類型

    在下面這個若是不是用global,後面x和username打印的全局的值,就是1,jason。若是你使用了global,改變了全局變量的值,在下面設置x = 999,username = 'egon',打印的值也是這個。

    

    nonlocal:局部修改局部(函數嵌套)

    若是沒有加nonlocal,x在局部找值,x=1。nonlocal 修改了前面x的值,在打印的時候變成2

          

    總結:global:局部修改全局,若是有多個,用逗號隔開

          nonlocal:局部修改局部,若是有多個,用逗號隔開

相關文章
相關標籤/搜索