国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

SICP Python 描述 1.3 定義新的函數(shù)

SegmentFault / 2075人閱讀

摘要:到目前為止,我們的環(huán)境只包含全局幀。要注意函數(shù)名稱是重復(fù)的,一個(gè)在幀中,另一個(gè)是函數(shù)的一部分。運(yùn)算符字表達(dá)式是全局幀中發(fā)現(xiàn)的名稱,綁定到了內(nèi)建的加法函數(shù)上。嚴(yán)格來(lái)說(shuō),這并不是問題所在不同局部幀中的的綁定是不相關(guān)的。

1.3 定義新的函數(shù)

來(lái)源:1.3 Defining New Functions

譯者:飛龍

協(xié)議:CC BY-NC-SA 4.0

我們已經(jīng)在 Python 中認(rèn)識(shí)了一些在任何強(qiáng)大的編程語(yǔ)言中都會(huì)出現(xiàn)的元素:

數(shù)值是內(nèi)建數(shù)據(jù),算數(shù)運(yùn)算是函數(shù)。

嵌套函數(shù)提供了組合操作的手段。

名稱到值的綁定提供了有限的抽象手段。

現(xiàn)在我們將要了解函數(shù)定義,一個(gè)更加強(qiáng)大的抽象技巧,名稱通過它可以綁定到復(fù)合操作上,并可以作為一個(gè)單元來(lái)引用。

我們通過如何表達(dá)“平方”這個(gè)概念來(lái)開始。我們可能會(huì)說(shuō),“對(duì)一個(gè)數(shù)求平方就是將這個(gè)數(shù)乘上它自己”。在 Python 中就是:

>>> def square(x):
        return mul(x, x)

這定義了一個(gè)新的函數(shù),并賦予了名稱square。這個(gè)用戶定義的函數(shù)并不內(nèi)建于解釋器。它表示將一個(gè)數(shù)乘上自己的復(fù)合操作。定義中的x叫做形式參數(shù),它為被乘的東西提供一個(gè)名稱。這個(gè)定義創(chuàng)建了用戶定義的函數(shù),并且將它關(guān)聯(lián)到名稱square上。

函數(shù)定義包含def語(yǔ)句,它標(biāo)明了(名稱)和一列帶有名字的(形式參數(shù))。之后,return(返回)語(yǔ)句叫做函數(shù)體,指定了函數(shù)的(返回表達(dá)式),它是函數(shù)無(wú)論什么時(shí)候調(diào)用都需要求值的表達(dá)式。

def ():
    return 

第二行必須縮進(jìn)!按照慣例我們應(yīng)該縮進(jìn)四個(gè)空格,而不是一個(gè)Tab,返回表達(dá)式并不是立即求值,它儲(chǔ)存為新定義函數(shù)的一部分,并且只在函數(shù)最終調(diào)用時(shí)會(huì)被求出。(很快我們就會(huì)看到縮進(jìn)區(qū)域可以跨越多行。)

定義了square之后,我們使用調(diào)用表達(dá)式來(lái)調(diào)用它:

>>> square(21)
441
>>> square(add(2, 5))
49
>>> square(square(3))
81

我們也可以在構(gòu)建其它函數(shù)時(shí),將square用作構(gòu)建塊。列入,我們可以輕易定義sum_squares函數(shù),它接受兩個(gè)數(shù)值作為參數(shù),并返回它們的平方和:

>>> def sum_squares(x, y):
        return add(square(x), square(y))
>>> sum_squares(3, 4)
25

用戶定義的函數(shù)和內(nèi)建函數(shù)以同種方法使用。確實(shí),我們不可能在sum_squares的定義中分辨出square是否構(gòu)建于解釋器中,從模塊導(dǎo)入還是由用戶定義。

1.3.1 環(huán)境

我們的 Python 子集已經(jīng)足夠復(fù)雜了,但程序的含義還不是非常明顯。如果形式參數(shù)和內(nèi)建函數(shù)具有相同名稱會(huì)如何呢??jī)蓚€(gè)函數(shù)是否能共享名稱而不會(huì)產(chǎn)生混亂呢?為了解決這些疑問,我們必須詳細(xì)描述環(huán)境。

表達(dá)式求值所在的環(huán)境由幀的序列組成,它們可以表述為一些盒子。每一幀都包含了一些綁定,它們將名稱和對(duì)應(yīng)的值關(guān)聯(lián)起來(lái)。全局幀只有一個(gè),它包含所有內(nèi)建函數(shù)的名稱綁定(只展示了absmax)。我們使用地球符號(hào)來(lái)表示全局。

賦值和導(dǎo)入語(yǔ)句會(huì)向當(dāng)前環(huán)境的第一個(gè)幀添加條目。到目前為止,我們的環(huán)境只包含全局幀。

>>> from math import pi
>>> tau = 2 * pi

def語(yǔ)句也將綁定綁定到由定義創(chuàng)建的函數(shù)上。定義square之后的環(huán)境如圖所示:

這些環(huán)境圖示展示了當(dāng)前環(huán)境中的綁定,以及它們所綁定的值(并不是任何幀的一部分)。要注意函數(shù)名稱是重復(fù)的,一個(gè)在幀中,另一個(gè)是函數(shù)的一部分。這一重復(fù)是有意的,許多不同的名字可能會(huì)引用相同函數(shù),但是函數(shù)本身只有一個(gè)內(nèi)在名稱。但是,在環(huán)境中由名稱檢索值只檢查名稱綁定。函數(shù)的內(nèi)在名稱不在名稱檢索中起作用。在我們之前看到的例子中:

>>> f = max
>>> f

名稱max是函數(shù)的內(nèi)在名稱,以及打印f時(shí)我們看到的名稱。此外,名稱maxf在全局環(huán)境中都綁定到了相同函數(shù)上。

在我們介紹 Python 的附加特性時(shí),我們需要擴(kuò)展這些圖示。每次我們這樣做的時(shí)候,我們都會(huì)列出圖示可以表達(dá)的新特性。

新的環(huán)境特性:賦值和用戶定義的函數(shù)定義。

1.3.2 調(diào)用用戶定義的函數(shù)

為了求出運(yùn)算符為用戶定義函數(shù)的調(diào)用表達(dá)式,Python 解釋器遵循與求出運(yùn)算符為內(nèi)建函數(shù)的表達(dá)式相似的過程。也就是說(shuō),解釋器求出操作數(shù)表達(dá)式,并且對(duì)產(chǎn)生的實(shí)參調(diào)用具名函數(shù)。

調(diào)用用戶定義的函數(shù)的行為引入了第二個(gè)局部幀,它只能由函數(shù)來(lái)訪問。為了對(duì)一些實(shí)參調(diào)用用戶定義的函數(shù):

在新的局部幀中,將實(shí)參綁定到函數(shù)的形式參數(shù)上。

在當(dāng)前幀的開頭以及全局幀的末尾求出函數(shù)體。

函數(shù)體求值所在的環(huán)境由兩個(gè)幀組成:第一個(gè)是局部幀,包含參數(shù)綁定,之后是全局幀,包含其它所有東西。每個(gè)函數(shù)示例都有自己的獨(dú)立局部幀。

這張圖包含兩個(gè)不同的 Python 解釋器層面:當(dāng)前的環(huán)境,以及表達(dá)式樹的一部分,它和要求值的代碼的當(dāng)前一行相關(guān)。我們描述了調(diào)用表達(dá)式的求值,用戶定義的函數(shù)(藍(lán)色)表示為兩部分的圓角矩形。點(diǎn)線箭頭表示哪個(gè)環(huán)境用于在每個(gè)部分求解表達(dá)式。

上半部分展示了調(diào)用表達(dá)式的求值。這個(gè)調(diào)用表達(dá)式并不在任何函數(shù)里面,所以他在全局環(huán)境中求值。所以,任何里面的名稱(例如square)都會(huì)在全局幀中檢索。

下半部分展示了square函數(shù)的函數(shù)體。它的返回表達(dá)式在上面的步驟1引入的新環(huán)境中求值,它將square的形式參數(shù)x的名稱綁定到實(shí)參的值-2上。

環(huán)境中幀的順序會(huì)影響由表達(dá)式中的名稱檢索返回的值。我們之前說(shuō)名稱求解為當(dāng)前環(huán)境中與這個(gè)名稱關(guān)聯(lián)的值。我們現(xiàn)在可以更精確一些:

名稱求解為當(dāng)前環(huán)境中,最先發(fā)現(xiàn)該名稱的幀中,綁定到這個(gè)名稱的值。

我們關(guān)于環(huán)境、名稱和函數(shù)的概念框架建立了求值模型,雖然一些機(jī)制的細(xì)節(jié)仍舊沒有指明(例如綁定如何實(shí)現(xiàn)),我們的模型在描述解釋器如何求解調(diào)用表示上,變得更準(zhǔn)確和正確。在第三章我們會(huì)看到這一模型如何用作一個(gè)藍(lán)圖來(lái)實(shí)現(xiàn)編程語(yǔ)言的可工作的解釋器。

新的環(huán)境特性:函數(shù)調(diào)用。

1.3.3 示例:調(diào)用用戶定義的函數(shù)

讓我們?cè)僖淮慰紤]兩個(gè)簡(jiǎn)單的定義:

>>> from operator import add, mul
>>> def square(x):
        return mul(x, x)
>>> def sum_squares(x, y):
        return add(square(x), square(y))

以及求解下列調(diào)用表達(dá)式的過程:

>>> sum_squares(5, 12)
169

Python 首先會(huì)求出名稱sum_squares,它在全局幀綁定了用戶定義的函數(shù)?;镜臄?shù)字表達(dá)式 5 和 12 求值為它們所表達(dá)的數(shù)值。

之后,Python 調(diào)用了sum_squares,它引入了局部幀,將x綁定為 5,將y綁定為 12。

這張圖中,局部幀指向它的后繼,全局幀。所有局部幀必須指向某個(gè)先導(dǎo),這些鏈接定義了當(dāng)前環(huán)境中的幀序列。

sum_square的函數(shù)體包含下列調(diào)用表達(dá)式:

   add     (  square(x)  ,  square(y)  )
 ________     _________     _________
"operator"   "operand 0"   "operand 1"

全部三個(gè)子表達(dá)式在當(dāng)前環(huán)境中求值,它開始于標(biāo)記為sum_squares的幀。運(yùn)算符字表達(dá)式add是全局幀中發(fā)現(xiàn)的名稱,綁定到了內(nèi)建的加法函數(shù)上。兩個(gè)操作數(shù)子表達(dá)式必須在加法函數(shù)調(diào)用之前依次求值。兩個(gè)操作數(shù)都在當(dāng)前環(huán)境中求值,開始于標(biāo)記為sum_squares的幀。在下面的環(huán)境圖示中,我們把這一幀叫做A,并且將指向這一幀的箭頭同時(shí)替換為標(biāo)簽A。

在使用這個(gè)局部幀的情況下,函數(shù)體表達(dá)式mul(x, x)求值為 25。

我們的求值過程現(xiàn)在輪到了操作數(shù) 1,y的值為 12。Python 再次求出square的函數(shù)體。這次引入了另一個(gè)局部環(huán)境幀,將x綁定為 12。所以,操作數(shù) 1 求值為 144。

最后,對(duì)實(shí)參 25 和 144 調(diào)用加法會(huì)產(chǎn)生sum_squares函數(shù)體的最終值:169。

這張圖雖然復(fù)雜,但是用于展示我們目前為止發(fā)展出的許多基礎(chǔ)概念。名稱綁定到值上面,它延伸到許多局部幀中,局部幀在唯一的全局幀之上,全局幀包含共享名稱。表達(dá)式為樹形結(jié)構(gòu),以及每次子表達(dá)式包含用戶定義函數(shù)的調(diào)用時(shí),環(huán)境必須被擴(kuò)展。

所有這些機(jī)制的存在確保了名稱在表達(dá)式中正確的地方解析為正確的值。這個(gè)例子展示了為什么我們的模型需要所引入的復(fù)雜性。所有三個(gè)局部幀都包含名稱x的綁定。但是這個(gè)名稱在不同的幀中綁定到了不同的值上。局部幀分離了這些名稱。

1.3.4 局部名稱

函數(shù)實(shí)現(xiàn)的細(xì)節(jié)之一是實(shí)現(xiàn)者對(duì)形式參數(shù)名稱的選擇不應(yīng)影響函數(shù)行為。所以,下面的函數(shù)應(yīng)具有相同的行為:

>>> def square(x):
        return mul(x, x)
>>> def square(y):
        return mul(y, y)

這個(gè)原則 -- 也就是函數(shù)應(yīng)不依賴于編寫者選擇的參數(shù)名稱 -- 對(duì)編程語(yǔ)言來(lái)說(shuō)具有重要的結(jié)果。最簡(jiǎn)單的結(jié)果就是函數(shù)參數(shù)名稱應(yīng)保留在函數(shù)體的局部范圍中。

如果參數(shù)不位于相應(yīng)函數(shù)的局部范圍中,square的參數(shù)x可能和sum_squares中的參數(shù)x產(chǎn)生混亂。嚴(yán)格來(lái)說(shuō),這并不是問題所在:不同局部幀中的x的綁定是不相關(guān)的。我們的計(jì)算模型具有嚴(yán)謹(jǐn)?shù)脑O(shè)計(jì)來(lái)確保這種獨(dú)立性。

我們說(shuō)局部名稱的作用域被限制在定義它的用戶定義函數(shù)的函數(shù)體中。當(dāng)一個(gè)名稱不能再被訪問時(shí),它就離開了作用域。作用域的行為并不是我們模型的新事實(shí),它是環(huán)境的工作方式的結(jié)果。

1.3.5 實(shí)踐指南:選擇名稱

可修改的名稱并不代表形式參數(shù)的名稱完全不重要。反之,選擇良好的函數(shù)和參數(shù)名稱對(duì)于函數(shù)定義的人類可解釋性是必要的。

下面的準(zhǔn)則派生于 Python 的代碼風(fēng)格指南,可被所有(非反叛)Python 程序員作為指南。一些共享的約定會(huì)使社區(qū)成員之間的溝通變得容易。遵循這些約定有一些副作用,我會(huì)發(fā)現(xiàn)你的代碼在內(nèi)部變得一致。

函數(shù)名稱應(yīng)該小寫,以下劃線分隔。提倡描述性的名稱。

函數(shù)名稱通常反映解釋器向參數(shù)應(yīng)用的操作(例如print、add、square),或者結(jié)果(例如maxabssum)。

參數(shù)名稱應(yīng)小寫,以下劃線分隔。提倡單個(gè)詞的名稱。

參數(shù)名稱應(yīng)該反映參數(shù)在函數(shù)中的作用,并不僅僅是滿足的值的類型。

當(dāng)作用非常明確時(shí),單個(gè)字母的參數(shù)名稱可以接受,但是永遠(yuǎn)不要使用l(小寫的L)和O(大寫的o),或者I(大寫的i)來(lái)避免和數(shù)字混淆。

周期性對(duì)你編寫的程序復(fù)查這些準(zhǔn)則,不用多久你的名稱會(huì)變得十分 Python 化。

1.3.6 作為抽象的函數(shù)

雖然sum_squares十分簡(jiǎn)單,但是它演示了用戶定義函數(shù)的最強(qiáng)大的特性。sum_squares函數(shù)使用square函數(shù)定義,但是僅僅依賴于square定義在輸入?yún)?shù)和輸出值之間的關(guān)系。

我們可以編寫sum_squares,而不用考慮如何計(jì)算一個(gè)數(shù)值的平方。平方計(jì)算的細(xì)節(jié)被隱藏了,并可以在之后考慮。確實(shí),在sum_squares看來(lái),square并不是一個(gè)特定的函數(shù)體,而是某個(gè)函數(shù)的抽象,也就是所謂的函數(shù)式抽象。在這個(gè)層級(jí)的抽象中,任何能計(jì)算平方的函數(shù)都是等價(jià)的。

所以,僅僅考慮返回值的情況下,下面兩個(gè)計(jì)算平方的函數(shù)是難以區(qū)分的。每個(gè)都接受數(shù)值參數(shù)并且產(chǎn)生那個(gè)數(shù)的平方作為返回值。

>>> def square(x):
        return mul(x, x)
>>> def square(x):
        return mul(x, x-1) + x

換句話說(shuō),函數(shù)定義應(yīng)該能夠隱藏細(xì)節(jié)。函數(shù)的用戶可能不能自己編寫函數(shù),但是可以從其它程序員那里獲得它作為“黑盒”。用戶不應(yīng)該需要知道如何實(shí)現(xiàn)來(lái)調(diào)用。Python 庫(kù)擁有這個(gè)特性。許多開發(fā)者使用在這里定義的函數(shù),但是很少有人看過它們的實(shí)現(xiàn)。實(shí)際上,許多 Python 庫(kù)的實(shí)現(xiàn)并不完全用 Python 編寫,而是 C 語(yǔ)言。

1.3.7 運(yùn)算符

算術(shù)運(yùn)算符(例如+-)在我們的第一個(gè)例子中提供了組合手段。但是我們還需要為包含這些運(yùn)算符的表達(dá)式定義求值過程。

每個(gè)帶有中綴運(yùn)算符的 Python 表達(dá)式都有自己的求值過程,但是你通常可以認(rèn)為他們是調(diào)用表達(dá)式的快捷方式。當(dāng)你看到

>>> 2 + 3
5

的時(shí)候,可以簡(jiǎn)單認(rèn)為它是

>>> add(2, 3)
5

的快捷方式。

中綴記號(hào)可以嵌套,就像調(diào)用表達(dá)式那樣。Python 運(yùn)算符優(yōu)先級(jí)中采用了常規(guī)的數(shù)學(xué)規(guī)則,它指導(dǎo)了如何解釋帶有多種運(yùn)算符的復(fù)合表達(dá)式。

>>> 2 + 3 * 4 + 5
19

和下面的表達(dá)式的求值結(jié)果相同

>>> add(add(2, mul(3, 4)) , 5)
19

調(diào)用表達(dá)式的嵌套比運(yùn)算符版本更加明顯。Python 也允許括號(hào)括起來(lái)的子表達(dá)式,來(lái)覆蓋通常的優(yōu)先級(jí)規(guī)則,或者使表達(dá)式的嵌套結(jié)構(gòu)更加明顯:

>>> (2 + 3) * (4 + 5)
45

和下面的表達(dá)式的求值結(jié)果相同

>>> mul(add(2, 3), add(4, 5))
45

你應(yīng)該在你的程序中自由使用這些運(yùn)算符和括號(hào)。對(duì)于簡(jiǎn)單的算術(shù)運(yùn)算,Python 在慣例上傾向于運(yùn)算符而不是調(diào)用表達(dá)式。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/45485.html

相關(guān)文章

  • SICP Python 描述 第三章 計(jì)算機(jī)程序的構(gòu)造和解釋 3.1 引言

    摘要:為通用語(yǔ)言設(shè)計(jì)解釋器的想法可能令人畏懼。但是,典型的解釋器擁有簡(jiǎn)潔的通用結(jié)構(gòu)兩個(gè)可變的遞歸函數(shù),第一個(gè)求解環(huán)境中的表達(dá)式,第二個(gè)在參數(shù)上調(diào)用函數(shù)。這一章接下來(lái)的兩節(jié)專注于遞歸函數(shù)和數(shù)據(jù)結(jié)構(gòu),它們是理解解釋器設(shè)計(jì)的基礎(chǔ)。 3.1 引言 來(lái)源:3.1 Introduction 譯者:飛龍 協(xié)議:CC BY-NC-SA 4.0 第一章和第二章描述了編程的兩個(gè)基本元素:數(shù)據(jù)和函數(shù)之間的...

    v1 評(píng)論0 收藏0
  • SICP Python 描述 3.4 異常

    摘要:的最常見的作用是構(gòu)造異常實(shí)例并拋出它。子句組只在執(zhí)行過程中的異常產(chǎn)生時(shí)執(zhí)行。每個(gè)子句指定了需要處理的異常的特定類。將強(qiáng)制轉(zhuǎn)為字符串會(huì)得到由返回的人類可讀的字符串。 3.4 異常 來(lái)源:3.4 Exceptions 譯者:飛龍 協(xié)議:CC BY-NC-SA 4.0 程序員必須總是留意程序中可能出現(xiàn)的錯(cuò)誤。例子數(shù)不勝數(shù):一個(gè)函數(shù)可能不會(huì)收到它預(yù)期的信息,必需的資源可能會(huì)丟失,或者網(wǎng)...

    pkhope 評(píng)論0 收藏0
  • SICP Python 描述 2.6 實(shí)現(xiàn)類和對(duì)象

    摘要:以這種方式實(shí)現(xiàn)對(duì)象系統(tǒng)的目的是展示使用對(duì)象隱喻并不需要特殊的編程語(yǔ)言。我們的實(shí)現(xiàn)并不遵循類型系統(tǒng)的明確規(guī)定。反之,它為實(shí)現(xiàn)對(duì)象隱喻的核心功能而設(shè)計(jì)。是分發(fā)字典,它響應(yīng)消息和。 2.6 實(shí)現(xiàn)類和對(duì)象 來(lái)源:2.6 Implementing Classes and Objects 譯者:飛龍 協(xié)議:CC BY-NC-SA 4.0 在使用面向?qū)ο缶幊谭妒綍r(shí),我們使用對(duì)象隱喻來(lái)指導(dǎo)程序...

    chenjiang3 評(píng)論0 收藏0
  • SICP Python 描述 1.2 編程元素

    摘要:程序用于在編程社群的成員之間交流這些想法。在編程中,我們處理兩種元素函數(shù)和數(shù)據(jù)。在中,我們可以使用賦值語(yǔ)句來(lái)建立新的綁定,它包含左邊的名稱和右邊的值。例如,它并不能處理賦值語(yǔ)句。這些圖解的必要部分是函數(shù)的表示。 1.2 編程元素 來(lái)源:1.2 The Elements of Programming 譯者:飛龍 協(xié)議:CC BY-NC-SA 4.0 編程語(yǔ)言是操作計(jì)算機(jī)來(lái)執(zhí)行任務(wù)...

    CoorChice 評(píng)論0 收藏0
  • SICP Python 描述 1.4 實(shí)踐指南:函數(shù)的藝術(shù)

    摘要:實(shí)踐指南函數(shù)的藝術(shù)來(lái)源譯者飛龍協(xié)議函數(shù)是所有程序的要素,無(wú)論規(guī)模大小,并且在編程語(yǔ)言中作為我們表達(dá)計(jì)算過程的主要媒介。目前為止,我們討論了函數(shù)的形式特性,以及它們?nèi)绾问褂谩5谝恍忻枋龊瘮?shù)的任務(wù)。 1.4 實(shí)踐指南:函數(shù)的藝術(shù) 來(lái)源:1.4 Practical Guidance: The Art of the Function 譯者:飛龍 協(xié)議:CC BY-NC-SA 4.0 函...

    lemon 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<