天天看點

Python基本文法_函數屬性 & 參數類型 & 偏函數的應用目錄前言軟體環境Python Module的程式入口函數的屬性Python函數的建立偏函數的應用

<a href="#%E7%9B%AE%E5%BD%95">目錄</a>

<a href="#%E5%89%8D%E8%A8%80">前言</a>

<a href="#%E8%BD%AF%E4%BB%B6%E7%8E%AF%E5%A2%83">軟體環境</a>

<a href="#python-module%E7%9A%84%E7%A8%8B%E5%BA%8F%E5%85%A5%E5%8F%A3">Python Module的程式入口</a>

<a href="#%E5%87%BD%E6%95%B0%E7%9A%84%E5%B1%9E%E6%80%A7">函數的屬性</a>

<a href="#python%E5%87%BD%E6%95%B0%E7%9A%84%E5%88%9B%E5%BB%BA">Python函數的建立</a>

<a href="#%E5%87%BD%E6%95%B0%E7%9A%84%E5%8F%82%E6%95%B0">函數的參數</a>

<a href="#%E5%BF%85%E5%A4%87%E5%8F%82%E6%95%B0">必備參數</a>

<a href="#%E7%BC%BA%E7%9C%81%E5%8F%82%E6%95%B0">預設參數</a>

<a href="#%E5%91%BD%E5%90%8D%E5%8F%82%E6%95%B0">命名參數</a>

<a href="#%E4%B8%8D%E5%AE%9A%E9%95%BF%E5%8F%82%E6%95%B0">不定長參數</a>

<a href="#%E5%8C%BF%E5%90%8D%E5%8F%82%E6%95%B0">匿名參數</a>

<a href="#%E5%81%8F%E5%87%BD%E6%95%B0%E7%9A%84%E5%BA%94%E7%94%A8">偏函數的應用</a>

Python除了有豐富的标準庫之外,還可以自己定義滿足自身需求的類和函數。本篇主要介紹如何建立Python自定義函數。

系統

UbuntuKylin 14.04

軟體

Python 2.7.4

IPython 4.0.0

因為一個Python的程式檔案同時也是一個子產品檔案,而且我們希望可以更好的實作類和函數的代碼重用性、節省記憶體資源、提高執行效率。即,我希望主程式僅是在被期望執行的時候才會被執行而不會自動執行。是以我們會在每一個Python module檔案中定義一個程式的入口,當我們直接執行Python module的時候會自動執行主程式。當我們一個Python module被别的程式導入時,則僅僅會導入在Python module檔案中定義的類和函數。

我們一般會在Python module檔案中的主程式前使用下面的一條語句:

__name__是子產品的一個屬性,其作用是調用目前子產品的名稱,若此子產品是直接執行時,__name__ == ‘__main__’ 。當此子產品是被其他程式import時,__name__的值為此子產品的名稱。

Update: 2016-10-09

Python module程式入口最大的好處在于我們可以利用上述的這個特性來為一個 Module 編寫測試代碼, 當我們直接運作這個 module 檔案的時候, 我們可以通過測試代碼的實作來檢驗我們所定義的函數的輸出和輸出是否正确, 為每一個由必要測設的 module 檔案寫上測試代碼是一個優秀的程式員所具備的程式設計習慣.

函數是對程式邏輯進行結構化或過程化的一種程式設計方法, 函數有助于節省代碼空間, 也可以利于保持程式一緻性(修改一處, 所有代用都會跟着改變).

函數的屬性可以在定義函數時同時定義函數屬性, 也可以在函數聲明外定義函數屬性.

EXAMPLE: 可以通過句點辨別符和直接指派的方法為一個函數添加屬性.

還可以通過下面這種方式來定義函數屬性

NOTE: 這裡可以看出函數對象的 <code>__dict__</code> 特殊屬性包含了函數對象的屬性和屬性值.

一般格式:

建立一個自定義函數需要遵循下面幾個規則:

1.函數代碼塊以def關鍵詞開始,接着函數辨別符、圓括号()和代碼塊起始辨別 : 号。

2.任何傳入參數和自變量都必須放在()。()内可以用于定義參數。當有多個參數時,使用逗号隔開。

3.函數體的第一行語句可以使用文檔字元串<code>"""Document"""</code>一般用作存放函數的使用說明。

在Python中,函數也是一個對象,( )中表示對可調用函數對象的一種排程,可調用的函數對象一定會繼承了可調用的方法call( )。這也是用來檢查一個函數可否能夠被調用的依據。

若輸出為True,表示對象functionName為可調用函數對象,其繼承了call()方法,是一個函數。

Python有下面幾種函數參數類型:

1.必備參數

2.命名參數

3.預設參數

4.不定長參數

5.匿名參數

必備參數是在自定義函數時,最常見的參數類型。必備參數的使用有下面幾點要求:

1.在調用函數時,以形參與實參對應的順序來确定形參的值并傳入函數。

2.調用此函數時,傳遞的實參的數量必須與聲明時定義的形參的數量一緻。

注意:當傳遞的參數數目不一緻時,會觸發下面的異常:

預設參數既預設參數。顧名思義,預設參數可以實作在調用函數卻沒有指定實參時,可以為形參數提供一個預設值。相對的,當預設參數對應的實參有傳遞值時,預設參數的預設值會被覆寫。進而實參的數目未必一定會與形參的數目一緻,因為使用了預設參數。格式:

注意:即便預設參數會為形參提供一個預設的值,但是在Python的編譯過程的文法檢查時,參數的比對依舊是按照順序傳遞。是以一般而言,當你希望使用預設參數的值的時候,需要在定義函數的參數清單時,預設參數一定要置于必備參數和命名參數之後。避免在參數傳遞的時候,實參在将參數清單前端的預設參數覆寫後,卻沒有實參傳遞給必備參數。下面是一個例子:

文法錯誤:非預設參數不能在預設參數之後

命名參數也稱之為關鍵字參數, 其僅針對函數的調用, 讓調用者通過函數調用中的參數名字指派來将實參映射到形參, 有下面幾個要點:

1.調用時,用指派的方式來為函數傳入參數,調用格式:

2.可以以任意順序來指定參數

下面舉一個命名參數和預設參數一結合使用的例子:

在上面的例子中使用了預設參數,當沒有實參傳遞到函數的時候,形參會使用預設值。但在有些情況中,我們希望可以重新指定形參input3的值,而且希望繼續使用input2的預設值。在大多數程式設計語言中,想要實作上面的要求,必須要使用3個參數來調用函數,即必須重新指定input2的值。但是在Python中因為命名參數類型,是以我們可以突破參數順序的限制。将上面的例子修改為:

可以看見,當我沒有傳遞input2,僅僅是傳遞了input1、input3,而input2還是使用了預設值,而不會因為沒有指定命名參數導緻input2被覆寫而input3使用預設值的情況。但是要注意的一點是,即便結合使用了命名參數和預設參數,仍然無法改變non-default parameter not follows the default parameter的文法規則。

不定長參數也稱之為參數組或備援參數, 當你希望一個函數可以接受處理比當初聲明定義函數時更多的參數,可以使用不定長參數。即,實作了函數的參數備援。當傳遞的實參數目比函數的形參更多時,一般會報錯。但函數中的不定長參數可以用來吸收多餘的參數。注意:不定長參數僅允許放到函數形參清單的最後。格式:

其中的 “*” 辨別了不定長參數為 (非關鍵字參數) 會存儲所有非關鍵字的備援參數(沒有在實參清單内指定關鍵字,EG. <code>name='Jmilkfan'</code>),并将備援的參數存儲為Tuple類型對象, 也可以向該形參傳遞一個 Tuple 類型的參數組, 兩者的效果是一樣的. 隻是前者在函數内處理成 Tuple 的形式, 後者在調用之前就已經整理成 Tuple 了。

Example1:

上面例子的函數中使用了不定長參數*indePara,來存放enter2多餘的enter3兩個實參。并且是以元組的資料類型來存儲。

Example2:

而 “**” 表示為一個 (關鍵字參數),以字典的資料類型來存儲備援實參, 也可以向該形參傳遞一個 Dict 類型的實參。

在調用函數時,使用key=value的映射關系元素,傳遞實參。本質上是傳遞了key的引用和value的資料兩個值,并且傳遞到函數中的**indePara字典類型。要注意這與命名參數的差別,命名參數是為了可以亂序傳遞實參,而不定長參數是為了将多餘的實參儲存在函數中的Tuple或Dictionary類型對象中。

注意:以Tuple或Dic作為形參吸收實按備援時,若實參中均沒有多餘的元素或沒有映射關系元素時,會自動的為函數中的Tuple或Dic類型對象填入空值,避免報錯。

還需要注意的是:實參的映射關系元素中的key,不可以與已經存在的普通形參同名。否則會報錯

主要是避免命名參數和不定長參數的沖突。

匿名函數,即lambda函數。此函數能夠快速的建立出單行最小行函數并用于任何需要函數的地方,使用匿名參數有下面幾個要點:

1.無須使用def關鍵字來進行聲明。

2.lambda函數可以接受任何數量的實參,但隻會且僅傳回一個表達式的值。

3.lambda函數不能包含有指令和多個表達式。

4.不能直接調用print語句,因為lambda函數是單行函數且此行隻能為表達式。

5.lambda函數擁有自己的命名空間,不能通路除自身參數清單之外的全局命名空間内的參數。

6.lambda最大的優勢在于,可以不占用棧記憶體進而增加執行效率。

lambda函數的定義格式:

調用格式:

Example:

lambda在定義時會傳回一個需要接收的函數對象,在調用後會傳回一個類型對象。

偏函數的概念:就是将函數式程式設計、預設參數和備援參數結合在一起,将任意數量(順序)的參數轉化為另一個帶有剩餘參數的函數對象,進而實作截取函數功能(偏向)的效果。

NOTE:偏函數需要 functools Module 的支援。

EXAMPLE 1:将二進制數轉化為十進制

一般而言我們會使用上述的方式來執行,但有些時候會覺得能不能将 int() 函數的 base 參數臨時的設定成預設參數呢?這樣的話就可以獲得一個專門為了實作 *将二進制數轉化為十進制

* 功能的函數了。下面就是偏函數其中一個小的應用執行個體:

将 int() 函數的 base 參數定義為預設參數,并傳回給一個新的變量,這樣就像是生成了一個新的函數,EG.

<code>baseTwo(x) == int(x, base=2)</code>。

除此之外,我們還可以利用函數屬性的特性來為這個 “新定義” 的函數編寫文檔。