Python學習,第八課 - 函數

本次講解函數,因爲內容比較多,小編列了個大綱,主要有一下內容:python

1. 函數基本語法及特性算法

2. 函數參數數據結構

3.局部變量函數

4. 返回值性能

5.嵌套函數學習

6.遞歸spa

7.匿名函數code

8.高階函數blog

9.內置函數遞歸

 

1. 函數基本語法及特性

函數的定義:函數是指將一組語句的集合經過一個名字(函數名)封裝起來,要想執行這個函數,只需調用其函數名便可

函數的特性:

  1. 減小重複代碼
  2. 使程序變的可擴展
  3. 使程序變的易維護

函數的語法定義

直接上代碼:

# def 是定義函數的關鍵字

def test():#test既是函數名
    print('學習Python的第一個函數')
    
test() #調用函數

 

同時函數也能夠帶參數

a, b = 1, 3


# 帶參函數
def test(x, y):  # x 和 y 便是在咱們調用函數時傳入的參數
    return x + y  # 返回執行的結果


c = test(a, b)  # 把函數返回結果賦值給 C
print(c)

 

 

2. 函數參數

在說函數參數前,你們須要瞭解一個知識點,形參 & 實參

何爲形參?

既變量只有在被調用時才分配內存單元,在調用結束時,即刻釋放所分配的內存單元。

所以,形參只在函數內部有效,函數調用結束返回主調用函數後則不能再使用該形參變量

何爲實參?

既能夠是常量、變量、表達式、函數等,不管實參是何種類型的量,在進行函數調用時,它們都必須有肯定的值,以便把這些值傳送給形參。

所以應預先用賦值,輸入等辦法使參數得到肯定值

這麼說可能有些不理解,仍是來個實例讓你們更加清晰:

a, b = 1, 3


def test(x, y):  # x 和 y 便是形參
    return x + y

c = test(a, b)  # a,b既是實參
print(c)

 

 

關鍵參數

上面的例子中,咱們調用函數傳參是根據函數的形參位置來傳遞的。

既 a 傳給 x ,b 傳給 y。這種叫作位置參數。

咱們還可使用關鍵參數,既傳遞的時候給函數的參數名傳遞你的值:

a, b = 1, 3


# 帶參函數
def test(x, y):
    return x + y


c = test(y=a, x=b)#這裏把 a 傳給 y , b 傳給 x
print(c)

 

這樣參數就能夠不用按照順序傳遞,根據參數名傳遞給函數。

咱們甚至能夠把位置參數和關鍵參數同時使用:

a, b = 1, 3


def test(x, y):
    return x + y


c = test(1, y=b)
print(c)

 

若是同時使用必定要注意:關鍵參數必需要放在位置參數的後面,而且已經傳值的位置參數不能再用關鍵參數

下面是一些錯誤的用法:

c = test(x=a, b)
#報錯:TypeError: test() got multiple values for argument 'x'
c = test(a, x=b)
#報錯:TypeError: test() got multiple values for argument 'x'

 

 

默認參數

參數還能夠設置一個默認值,這樣咱們在調用的時候既能夠不傳參給默認參數

def test(x, y, z=9):  # 設置了 z 的默認值是 9
    print(x + y + z)

test(1, 3)#若是咱們第三個參數也就是z 不傳的話,z的默認值就是9
test(1, 3, 10)#咱們傳了第三個參數,則 z 的值就變成10

 

 

非固定參數

所謂非固定參數就是能夠傳遞任意個數的參數,好比你的函數在定義的時候不能肯定用戶想傳入多少個參數,就可使用

def test(*args):  # 使用 *args, 這裏args能夠改爲任意變量名,可是不建議這麼作。
    print(args)


test()
# 輸出結果:()
test(1, 2)
# 輸出結果:(1, 2)
test(1, 2, '承受', 'Python')
# 輸出結果:(1, 2, '承受', 'Python')

 

調用函數能夠傳入任意個數的參數,而後轉換成 元組 的形式

 

3.局部變量

局部變量:就是隻能在局部使用的變量

name = 'Cheng Shou'


def change_name(name):
    print('改變前:', name)
    name = '承受'
    print('改變後:', name)


change_name(name)

print('在外面在看下name的值:', name)

#輸出結果:
#改變前: Cheng Shou
#改變後: 承受
#在外面在看下name的值: Cheng Shou

 

從上面的例子你們發現了沒?函數裏面的name修改了,函數外面的name沒有改變。

其實函數裏面的name 就是局部變量,他並無調用外部的name。

 

那函數裏面就不能使用全局變量了嗎?非要用也是能夠的

name = 'Cheng Shou'


def change_name():
    global name #在函數中使用global既可
    print('改變前:', name)
    name = '承受'
    print('改變後:', name)


change_name()

print('在外面在看下name的值:', name)

#輸出結果:
#改變前: Cheng Shou
#改變後: 承受
#在外面在看下name的值: 承受

 

使用global 既可,咱們的全局變量也被修改了。

固然不建議這麼作。

 

全局變量與局部變量

在子程序中定義的變量稱爲局部變量,在程序的一開始定義的變量稱爲全局變量。
全局變量做用域是整個程序,局部變量做用域是定義該變量的子程序。
當全局變量與局部變量同名時:
在定義局部變量的子程序內,局部變量起做用;在其它地方全局變量起做用

 

4. 返回值

其實咱們第一個例子中就有用到返回值,既 return 語句。return能夠吧函數的執行結果返回

返回值記住兩點:

1.函數在執行過程當中只要遇到 return 語句就會中止函數的執行,而且返回結果。因此 return 語句出現就表明着函數結束

2.若是函數中未使用 return ,那函數執行完畢後,返回的值爲 None

 

5.嵌套函數

顧名思義就是函數裏面套函數,小編看到這個也是心裏驚呼一聲:python 果真牛掰

那麼怎麼套呢,上代碼:

name = 'Cheng Shou'


def change_name():
    name = '小承'

    def change_name2():
        name = '小受'
        print('第三層:', name)

    change_name2() # 調用內存函數
    print('第二層:', name)


change_name()
print('最外層:', name)

#輸出結果:
#第三層: 小受
#第二層: 小承
#最外層: Cheng Shou

 

神奇吧,一層套一層,跟俄羅斯套娃同樣

至於這個嵌套函數什麼做用,以後學習到裝飾器的時候咱們就知道了。

 

6.遞歸

在函數內部,能夠調用其餘函數。若是一個函數在內部調用自身自己,這個函數就是遞歸函數。

說白了,就是在函數裏面調用自身函數

def subtraction(n):
    print(n)
    if n < 1:
        return n
    return subtraction(n-1)

subtraction(5)

#輸出結果:
#5
#4
#3
#2
#1
#0

 

注意:python默認的遞歸深度是頗有限的(默認是1000),所以當遞歸深度超過999的樣子,就會引起這樣的一個異常。

報錯:RecursionError: maximum recursion depth exceeded while calling a Python object

若是你的業務須要遞歸深度超過1000,則須要修改遞歸深度的值

import sys
sys.setrecursionlimit(10000)

 

導入sys模塊,而後設置,須要多大就設置多大既可。

通常咱們的業務代碼不建議超過默認深度,不然代碼性能很差。

在二分查找的時候,咱們會用到遞歸,不過這講到算法問題本篇就直接帶過,後續有時間小編在寫一篇算法相關的文章

遞歸特性:

1. 必須有一個明確的結束條件

2. 每次進入更深一層遞歸時,問題規模相比上次遞歸都應有所減小

3. 遞歸效率不高,遞歸層次過多會致使棧溢出(在計算機中,函數調用是經過棧(stack)這種數據結構實現的,每當進入一個函數調用,棧就會加一層棧幀,每當函數返回,棧就會減一層棧幀。因爲棧的大小不是無限的,因此,遞歸調用的次數過多,會致使棧溢出)

 

7.匿名函數

匿名函數就是不須要顯式的指定函數

def test(n):
    return n + 1

print(test(2))
# 上面的函數修改爲匿名函數後
test = lambda n: n + 1
print(test(2))

 

通常匿名函數是和其它函數搭配使用的,以下

print(map(lambda x: x ** 2, [1, 2, 3, 4, 5]) )
#輸出:[1, 4, 9, 16, 25]

 

 

8.高階函數

變量能夠指向函數,函數的參數能接收變量,那麼一個函數就能夠接收另外一個函數做爲參數,這種函數就稱之爲高階函數。

簡單的說就是把函數當作參數傳遞給另外一個函數,在函數中調用傳遞過來的函數。

def add(x, y, func):
    return func(x) + func(y)

def square(n):
    return n ** 2

res = add(3, 6, square)
print(res)

 

這裏把square函數,傳遞給了add ,而且在add中使用了 square函數。這便實現了高階函數

 

9.內置函數

直接展現一張圖,不作詳解,你們使用到的時候在瞭解既可。

相關文章
相關標籤/搜索