Python學習筆記__4.2章 返回函數

來源:互聯網
上載者:User

標籤:程式設計語言   python   

# 這是學習廖雪峰老師python教程的學習筆記

1、函數作為傳回值

高階函數除了可以接受函數作為參數外,還可以把函數作為結果值返回。

# 累加函數

def external(*args):

    def internal():

        ax = 0

        for n in args:

            ax = ax + n

        return ax

    return internal  # external的傳回值是internal

 

# 調用external()

f = external(1, 3, 5, 7, 9)   #這裡的 f是一個函數,相當於internal,external 函數的參數會傳給internal

>>> f()  # 調用函數,==inernal()

25

 

在函數 external 中又定義了函數inernal,並且,內建函式inernal 可以引用外部函數external 的參數和局部變數,當external 返回函數internal 時,相關參數和變數都儲存在返回的函數中,這樣的程式我們稱為 閉包

註:,每次調用 external 都會返回一個新的函數,即使傳入相同的參數

 

2、閉包

2.1、理解閉包-1

在電腦科學中,閉包(英語:Closure),又稱詞法閉包(Lexical Closure)或函數閉包(function closures),是引用了自由變數的函數。這個被引用的自由變數將和這個函數一同存在,即使已經離開了創造它的環境也不例外。所以,有另一種說法認為閉包是由函數和與其相關的引用環境組合而成的實體。閉包在運行時可以有多個執行個體,不同的引用環境和相同的函數組合可以產生不同的執行個體。

2.2、理解閉包-2

在函數中可以(嵌套)定義另一個函數時,如果內部的函數引用了外部的函數的變數,則可能產生閉包。運行時,一旦外部的 函數被執行,一個閉包就形成了,閉包中包含了內建函式的代碼,以及所需外部函數中的變數的引用。其中所引用的變數稱作上值(upvalue)。

2.3、理解閉包-3

Python 中通俗一點來說,如果在一個函數內部,嵌套了函數,這個內建函式對(非全域範圍)外部範圍的變數進行引用,那麼這個內建函式稱為閉包。閉包每次運行都能記住引用的外部範圍的變數的值。

2.4、個人理解

  • 外部函數執行完畢,返回內建函式後即消失。#      external(1,3,5,7) 執行完畢,返回internal

  • 此時,外部函數裡定義的變數依然會和內建函式一同存在。#  external函數傳入的參數      args=[1,3,5,7],同internal 一起存在

  • 變數和內建函式組成一個環境。 #      interal

  • 為 interal函數起個‘別名’ #  f = external(1, 3,      5, 7, 9) 。 即  f == internal

  • 執行 internal 函數 # f()

2.5、執行個體分析

1、f 和 f()

def count():

    fs = []

    for i in range(1, 4):

        def f():

             return i*i

        fs.append(f)    # 注意這裡,fs.append 的是一個函數

    return fs

 

f1, f2, f3 = count()

                    1、fs.append(f)

  • 外部函數count 的傳回值是 fs。

  • fs 是一個list。list裡是 f 函數。

  • f1, f2, f3 =      count(),即 f1,f2,f3 = f 。 調用時 f()的結果就是 f(3)

  • f 函數外是一個for迴圈。fs裡調用的是 f 函數,for迴圈的中間值無處可存,最後 fs=[f(3),f(3),f(3)]

                            2、fs.append(f())

  • 如果把 f 換成 f() 呢?

  • 此時fs.append的就是算好的值,返回的fs就是 fs=[1,4,9],不再有閉包

  • f1, f2, f3 =      count(),即 f1=1 , f2=4 , f3=9

 

# 在閉包中使用迴圈變數

def count():

    def f(j):         #  引入 f() 函數 ,使得 for 迴圈的 中間值得以儲存

        def g():

            return j*j

        return g

    fs = []

    for i in range(1, 4):

        fs.append(f(i)) # f(i)立刻被執行,因此i的當前值被傳入fs

    return fs

f1, f2, f3 = count()

 

f1() == f(1)

f2() == f(2)

f3() == f(3)

 

3、範圍

python內的範圍有:

  1. 本地範圍(Local)   # 函數內部定義的

  2. 嵌套範圍(Enclosing function      locals)  #  外層函數的 參數a ,內層函數引用a時,就是從嵌套範圍中拿

  3. 全域範圍(Global)   # 函數體外 定義的

  4. 內建範圍(buitins模組)   # 編譯層內建的

python在引用一個變數時,對這個變數的搜尋 從 1) --》 4)

3.1、函數內修改全域變數

x = 99

def func()

    global x             #  global 告訴 函數,這裡的x 是全域變數。你不要在 自己的 本地範圍 建立 x 變數了

    x = 88

3.2、內層函數 修改 嵌套域變數

def func():

    count = 1

    def foo():

        nonlocal count    # nonlocal 告訴 內建函數foo(),這裡引用的是外層函數的count 變數,你不要在 自己的 本地範圍建立變數了

        count = 12

    foo()

    print(count)

 

4、例子

1、利用閉包返回一個計數器函數,每次調用它返回遞增整數:

# -*- coding: utf-8 -*-

 

def createCounter():

    n=0

    def counter():

        nonlocal n         #  指明引用的n 不是函數內部定義的

        n+=1

        return n

    return counter

 

 

 

# 測試:
counterA = createCounter()
print(counterA(), counterA(), counterA(), counterA(), counterA()) # 1 2 3 4 5
counterB = createCounter()
if [counterB(), counterB(), counterB(), counterB()] == [1, 2, 3, 4]:
    print('測試通過!')
else:
    print('測試失敗!')


Python學習筆記__4.2章 返回函數

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.