天天看點

給妹子講python-S01E17函數的基本特征

今天開始,我們來講講函數,簡而言之一個函數就是将一些語句集合在一起的部件,它們能夠不止一次的在程式中運作。函數還能計算出一個傳回值,并能夠改變作為函數輸入的參數,而這些參數在代碼運作時也許每次“代入”的值都不相同。函數是python為了代碼最大程度的重用和最小化代碼備援而提供的最基本的程式結構。

函數有關的内容主要分為函數的基本概念、作用域以及參數傳遞,還有一些相關的進階概念,如裝飾器。

【妹子說】那這一節我們先學習函數的最基本用法吧

首先我們先學習一下在python中如何去編寫一個函數。今天我們先抛出點兒理論:需要注意的是,函數在python中同在C語言中是有所不同的。

第一:def引導一段可執行的代碼:

def本身是一個可執行的語句,函數此時并不存在,直到python運作了def後,函數才存在,def後面包含的就是函數語句。在典型的操作中,def語句在子產品檔案中編寫,并自然而然的在子產品檔案第一次被導入的時候生成定義的函數。

第二:函數也是對象。def建立了一個對象并将其指派給某一變量名。

當python運作到def語句時,它将會生成一個新的函數對象并将其指派給這個函數名。和普通對象指派一樣,函數名就成了某一個函數的引用。python中,萬物皆對象,是以函數也是一種對象,他可以指派給其他的變量名,并且可以儲存在清單之中。

第三:函數是通過指派語句(對象引用)傳遞的。

在python中,參數通過指派傳遞給了函數(也就是說,就像我們所學過的,使用對象引用),在python中,調用者以及函數通過引用共享對象,但是改變傳遞的可變對象可以改變調用者共享的那個對象。

第四:函數的多态性。可以傳遞任意類型的參數給函數,函數也可以傳回任意類型的對象。

其結果就是,函數常常可以用在很多類型的對象身上,任意支援相容接口(方法和表達式)的對象都能使用。

【妹子說】哎呀,說了這麼些理論,也夠枯燥的,那我們來看實際的例子吧:

沒問題

def func(a,b):

return a+b

other_name = func

print(other_name(1,2))

3

在這裡我們可以看到如何定義一個最簡單的函數,重要的是我們還将函數指派給一個不同的變量名,并通過新的變量名進行了調用。這說明了一點,在python中函數也是對象。

python的函數使用還是非常簡單的,我們再舉一個例子:主要描述了兩個方面:def定義(即函數的建立)和函數的調用(表達式告訴python去運作函數主體)

def func(x,y):

return x * y

print(func(2,4))

8

結合前面的例子我們可以看到,在例子中,參數x被指派為2,y被指派為4,經過函數主體運算,return傳回結果對象。

【妹子說】這和上面的例子不是一模一樣嗎?

别急,我們接着看:

print(func(3.14,8))

25.12

-

print(func('Ab',8))

AbAbAbAbAbAbAbAb

出現這種現象非常重要,我們在函數聲明時并沒有對參數和傳回值進行類型聲明,是以實際上,這些資料類型是依托調用者的傳入類型,即傳入什麼就是什麼,函數體的執行過程可能會因為參數類型的改變而發生變化。是以這裡出現了數字的乘法和字元串的重複這兩種似乎截然不同的現象。換句話說func函數的運作結果取決于傳遞給他的值。

函數中x *y表達式的意義完全取決于x和y的對象類型,在一個執行個體下執行時數值乘法,在另一個執行個體下執行是字元串的重複,python将對某一對象在某種文法下的合理性交由對象自身來判斷。

這種依賴于類型的行為稱為多态,其含義就是一個操作的意義取決于被操作對象的類型,因為python是動态類型語言,是以多态在python中随處可見。

如果傳遞的對象不支援這種預期的接口,那麼python會在*表達式運作時進行檢測,并自動抛出一個異常:

print(func('Ab','aa'))

Traceback (most recent call last):

File "E:/12homework/12homework.py", line 4, in <module>

File "E:/12homework/12homework.py", line 2, in func

return x * y

TypeError: can't multiply sequence by non-int of type 'str'

是以,這種多态的程式設計模型意味着必須測試代碼去檢測錯誤。

我們看一個例子:

def func(seq1, seq2):

res = []

for x in seq1:

if x in seq2:

res.append(x)

return res

模型中我們可以看到,調用者可以傳遞任何類型的參數,通過周遊兩個序列,尋找他們的交集,是以函數中使用任意可疊代對象作為參數都是合适的。并在最後将運算結果的清單對象返給調用者

print(func([1,2,3,4,5,6], (5,6,7,8)))

[5, 6]

print(func('spam', ('s','p','c','m')))

['s', 'p', 'm']

甚至使用清單解析式也可以

print(func([1,2,3,4], [x for x in (2,3,5)]))

[2, 3]

可以看出,這個函數也是多态的,他支援多種參數類型,記住,隻要支援對象接口----可進行資料疊代即可,第一個參數支援for循環,第二個參數支援成員測試,滿足上述條件的任意對象都可以使得函數正常工作,包括實際存在的實體序列,字元串、清單等,以及可疊代對象,檔案和字典等等,都可以傳入使用。

同時我們需要注意,函數的參數是通過指派而被傳入的,是以seq1和seq2是本地變量,結果清單對象是通過指派得到的,也是本地對象,所有的本地變量都在函數調用時出現,在函數退出時消失。

另外需要專門說明一點,return語句傳回結果對象給調用者,但是res對象本身會在函數調用結束時消失。

原文釋出時間為:2018-09-2

本文作者:給妹子講python

本文來自雲栖社群合作夥伴“

Python愛好者社群

”,了解相關資訊可以關注“

”。