1. 程式人生 > >【python小課堂專欄】python小課堂16 - 函式篇

【python小課堂專欄】python小課堂16 - 函式篇

python小課堂16 - 函式篇

前言

函式篇 ------ 說起函式,大家高中應該都學過類似的概念,函式指一個量隨著另一個量的變化而變化,而在程式設計中,函式的概念則不盡相同。舉個例子,比如打過dota的同學都知道,在dota中通過shift可以對英雄進行預操作,也就是當英雄還沒到某一地方時,我們可以通過shift鍵來設定好相應的路徑以及施法,來完成對英雄的提前操作,這樣起到的作用就是將操作模板化。

在這裡插入圖片描述

而相應的,在程式中,函式就是為了將程式碼進行模板化管理,它可以實現一些特定功能的小方法或是小程式。而在python小課堂之前的介紹中,其實就已經介紹過不少python自帶的函數了,比如print()、max()、ord()等。。

定義函式

通常在python中,我們可以類似下面的寫法去定義一個函式:

def print_hello(words):
  print('hello ' + words)
  
print_hello('world!')

>>> hello world!

def作為python中的關鍵標識字,全拼define 定義的意思,後面的print_hello作為函式的名稱,小括號裡面可以傳入不同的引數,以便外面呼叫時將引數傳入。想後面的print_hello(‘world!’)就是將’world!’ 傳入到print_hello中。

函式的引數

1. 形參和實參

其中print_hello(words): words代表的是函式的形參,形式上的引數。

其中print_hello(‘world!’): 'world!'代表的是函式的實參,即實際的引數。

2. 必須引數和關鍵字引數

想象一個實際場景,當我們在計算減法算數的時候,需要你手寫一個函式,傳入x,y並且將最終相加的結果打印出來。


def sub(x, y):
    sub = x - y
    print(sub)
sub(2,1)

>>> 1

呼叫add函式時,傳入的1,2稱之為必須引數,也就是實參,傳入時是有順序的,所以我們最終結果得到的是1,但是如果我們把sub(2,1)改成了sub(1,2)最終得到的結果就是-1,有沒有一種方法依然可以得到1呢?此時使用關鍵字引數即可實現。忽略實際引數傳入時的順序,寫法如下:

def sub(x, y):
    sub = x - y
    print(sub)
sub(y = 1,x = 2)

>>> 1

可以看到,在傳入實參時,我們可以指定對應的函式形參值,進行傳入對應的值,來達到無序傳入。關鍵字引數在一些原始碼中是經常被用到的!

3. 預設引數

場景更新一下!比如現在需要我們求一個半徑預設為1的圓形面積,半徑可以通過外界因素進行改變,請設計出對應的函式。程式碼如下:

def circle_area(r = 1):
    area = 3.14 * r
    print(area)
circle_area()

>>> 3.14

預設引數就是在形參處寫好一個預設值,若呼叫時沒有傳入值,則變數會取預設值。再來看下如果傳入值會發生什麼?

def circle_area(r = 1):
    area = 3.14 * r
    print(area)
circle_area(10)

>>> 31.400000000000002

可以看到外面呼叫10時,將形參r=1覆蓋掉了,最終算出來的結果以r=10為準。

函式的返回值

函式的返回值:通過return關鍵詞來進行返回,當我們呼叫函式時,可以將函式的處理結果返回到呼叫處,來看一個加法的函式例子:

def add(x, y):
    sum = x + y
    return sum

result = add(1, 3)
print(result)

>>> 4

在這裡插入圖片描述

如果什麼add函式不寫return值呢?來看下結果:

在這裡插入圖片描述

上面的例子可以看到,python函式預設return值為None,而#代表的是註釋,在程式碼中起到的作用是解釋當前程式碼的意思,是寫給人看的,並不執行。同樣的#只能註釋一行,要想註釋多行可以使用 ‘’’ 你的程式碼 ‘’’,""" 你的程式碼 “”" ,也就是所謂的三雙引號和三單引號。如下:

'''
def add(x, y):
    sum = x + y
    return sum
'''
"""
result = add(1, 3)
print(result)
"""

return關鍵詞在函式中也代表這停止的意思,也就說在函式中如果遇到return,那麼return後面的程式碼不會進行執行。如下:

在這裡插入圖片描述

python的序列解包

在python的函式中,返回值是可以有多個值的,比如現在有一個場景,讓你去超市買水果,然後你花錢買到了蘋果和香蕉。我用簡單的函式程式碼來演示下:

在這裡插入圖片描述

def buy(money):
    if money > 10:
        fruit_a = 'banana'
        fruit_b = 'apple'
        return fruit_a, fruit_b

fruit = buy(20)
print(type(fruit))
print(f'通過元組索引得到的值:{fruit[0]}, {fruit[1]}')
banana, apple = buy(20)
print(f'通過解包得到的值:{banana}, {apple}')

>>> <class 'tuple'>
>>> 通過元組索引得到的值:banana, apple
>>> 通過解包得到的值:banana,apple

可以看到,如果我們去超市買水果,身上帶了大於10塊錢的錢,那麼我就可以同時買到蘋果和香蕉,同時函式將兩個值一起返回,得到的是元組,在呼叫時解析時,可以直接對元組進行解包操作,直接定義對應變數的名稱即可!推薦用解包形式去得到函式多個返回值,因為邏輯非常清晰!

你不知道的python小知識點

1.python的系統遞迴引數

現在有一個場景,請你實現列印一句話hello!並且在函式內部呼叫自己本身。程式碼實現如下:

def print_hello(words):
  print(words)
  print_hello('hello')
print_hello('world!')

在這裡插入圖片描述

可以看到報錯了!錯誤中文大概意思是遞迴錯誤,超過最大遞迴深度。最大深度就是螢幕上的993次。

Tips:
遞迴 —> 遞迴的意思就是函式本身自己呼叫自己。比如上面的例子中,在print_hello函式中又呼叫了自己,所以python就會一直執行下去,但是python自身有檢測遞迴函式的機制,所以如果你寫了一個死迴圈這樣的遞迴,它會直接進行最大次數的嘗試並且報錯。常見的錯誤:在程式中若寫了一個死迴圈遞迴方法,最終報錯的資訊則是:MemoryError: stack overflow,也就是常說的棧記憶體溢位。

拓展知識:

在上一節中,我曾經說過一個python自帶的包,叫做sys。通過sys可以來設定遞迴函式的最大深度。請看下面的程式碼:

import sys
sys.setrecursionlimit(1000)

def print_hello(words):
  print(words)
  print_hello('hello')

print_hello('world!')

2. python的鏈式賦值
在python中,是支援鏈式賦值的,什麼是鏈式呢?就是類似將元素串起來形成一個鏈子一樣。如下:

a = b = c = 1
print(a, b, c)

>>> 1 1 1

3. "序列解包"賦值

道理和上面講過的序列解包差不多:

a, b, c = 1, 2, 3
print(a, b, c)

>>> 1 2 3

至此完!


有想學python的同學,歡迎關注公號:

在這裡插入圖片描述