Python3(3) Python 函數(shù)

本系列主要學(xué)習(xí)Python的基本使用和語法知識(shí),后續(xù)可能會(huì)圍繞著AI學(xué)習(xí)展開。
Python3 (1) Python語言的簡(jiǎn)介
Python3 (2) Python語法基礎(chǔ)
Python3 (3) Python函數(shù)
Python3 (4) Python高級(jí)特性
Python3 (5) Python 函數(shù)式編程
Python3 (6) Python 模塊
Python3 (7) Python 面向?qū)ο缶幊?/a>
Python3 (8) Python 面向?qū)ο蟾呒?jí)編程
Python3 (9) Python 錯(cuò)誤、調(diào)試和測(cè)試
Python3 (10) Python IO編程
Python3 (11) Python 進(jìn)程和線程
Python3 (12) Python 常用內(nèi)建模塊
Python3 (14) Python 網(wǎng)絡(luò)編程
函數(shù)部分主要有函數(shù)的調(diào)用、函數(shù)的定義、函數(shù)的參數(shù)(參數(shù)部分比較難,相對(duì)于java增加了好多新的概念,參數(shù)可以各種組合)、函數(shù)的遞歸。

函數(shù)的調(diào)用

為什么先強(qiáng)調(diào)函數(shù)的調(diào)用呢,因?yàn)镻ython有好多內(nèi)置函數(shù),可以為我們解決各種問題。舉幾個(gè)例子:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
//abs() 獲取絕對(duì)值,我們可以直接調(diào)用
x = abs(100)
//abs 賦值給a, 相當(dāng)于a指向了abs函數(shù),這也體現(xiàn)python賦值的強(qiáng)大之處
a = abs
y = a(-20)
// int、str ...數(shù)據(jù)轉(zhuǎn)化函數(shù),可以對(duì)數(shù)據(jù)進(jìn)行轉(zhuǎn)換,前提是可以相互轉(zhuǎn)換的數(shù)據(jù)
z = int('123')
s = str(True)
print(x, y,z,s)
//數(shù)學(xué)類函數(shù)
print('max(1, 2, 3) =', max(1, 2, 3))
print('min(1, 2, 3) =', min(1, 2, 3))
print('sum([1, 2, 3]) =', sum([1, 2, 3]))

輸出結(jié)果:

100 20 123 True
max(1, 2, 3) = 3
min(1, 2, 3) = 1
sum([1, 2, 3]) = 6

python內(nèi)置函數(shù)的調(diào)用中,如果參數(shù)不匹配會(huì)出現(xiàn) TypeError 錯(cuò)誤:

Traceback (most recent call last):
  File "F:/python/HelloWord/call_func.py", line 4, in <module>
    x = a(100,200)
TypeError: abs() takes exactly one argument (2 given)

函數(shù)的定義

在Python中,定義一個(gè)函數(shù)要使用def語句,依次寫出函數(shù)名括號(hào)、括號(hào)中的參數(shù)冒號(hào):,然后,在縮進(jìn)塊中編寫 函數(shù)體,函數(shù)的返回值用return語句返回,注意python中沒有大括號(hào)。

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import math
//自定義一個(gè)取絕對(duì)值的函數(shù)
def my_abs(x):
     //自定義類型異常捕獲機(jī)制,關(guān)鍵字 isinstance  
    if not isinstance(x, (int, float)):
        raise TypeError('bad operand type')
    if x >= 0:
        return x
    else:
        return -x

n = my_abs(-20)
print(n)
# TypeError: bad operand type:
# my_abs('123')

輸出結(jié)果:

20
  • 在函數(shù)中,一旦執(zhí)行到return時(shí),函數(shù)就執(zhí)行完畢,并將結(jié)果返回,如果沒有return 函數(shù)執(zhí)行完成后默認(rèn) return None , 函數(shù)中 return None 可以簡(jiǎn)寫成 return。
  • 自定義的函數(shù),參數(shù)類型不會(huì)像內(nèi)置函數(shù)拋出 TypeError 異常,可以自定義TypeError 異常,來保證函數(shù)的嚴(yán)謹(jǐn)性。

空函數(shù)

def no_fun():
    pass
print(no_fun())

輸出結(jié)果:

None

空函數(shù)的定義: 可以通過關(guān)鍵字 pass 來做函數(shù)體 意思很明顯,直接通過

函數(shù)返回值

python 中支持多參數(shù)返回,實(shí)質(zhì)上是返回一個(gè)tuple!

def move(x, y, step, angle=0):
    nx = x + step * math.cos(angle)
    ny = y - step * math.sin(angle)
    return nx, ny
// 多參數(shù)接收
x, y = move(100, 100, 60, math.pi / 6)
// 單參數(shù)接收
n =  move(100, 100, 60, math.pi / 6)
print(x, y,n)

輸出結(jié)果:

151.96152422706632 70.0 (151.96152422706632, 70.0)

函數(shù)參數(shù)

函數(shù)的參數(shù)定義非常的靈活,支持必選參數(shù)、位置參數(shù)、默認(rèn)參數(shù)、可變參數(shù)、關(guān)鍵字參數(shù)等、并且這些參數(shù)可以組合使用。

必選參數(shù)

def myPower(x):
    return x * x
print("myPower (2)= ",myPower(2))

輸出結(jié)果:

myPower(2) =  4

參數(shù)x為必選參數(shù),否則TypeError: myPower() missing 1 required positional argument: 'x'。

位置參數(shù)

def myPower(x,n):
    s = 1
    while n > 0:
        n = n - 1
        s = s * x
    return s

print("myPower = ",myPower(2,5))

輸出結(jié)果:

myPower =  32

myPower(x, n)函數(shù)有兩個(gè)參數(shù):x和n,這兩個(gè)參數(shù)都是位置參數(shù),調(diào)用函數(shù)時(shí),傳入的兩個(gè)值按照位置順序依次賦給參數(shù)x和n。

默認(rèn)參數(shù)

默認(rèn)參數(shù)相當(dāng)于java的重載,一個(gè)函數(shù)傳入不同個(gè)數(shù)的參數(shù),沒有傳的參數(shù),會(huì)有默認(rèn)參數(shù)來代替

def myPower(x,n = 2):
    s = 1
    while n > 0:
        n = n - 1
        s = s * x
    return s

print("myPower = ",myPower(2))

輸出結(jié)果:

myPower =  4
  • 注意定義函數(shù)時(shí),必選參數(shù)在前,默認(rèn)參數(shù)在后
  • 變化大的的默認(rèn)參數(shù)在前,變化小的默認(rèn)參數(shù)在后,符合使用規(guī)則
  • 默認(rèn)參數(shù)代替了java 中因?yàn)閰?shù)個(gè)數(shù)引起的重載,減少了函數(shù)的定義
  • 定義默認(rèn)參數(shù)要牢記一點(diǎn):默認(rèn)參數(shù)必須指向不變對(duì)象!
    比如定義一個(gè)函數(shù),傳入一個(gè)默認(rèn)參數(shù)list:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
def my_list(L=[]):
    L.append('END')
    return L
N = my_list([1,2,3,4,5])
print(N)
# 第一次調(diào)用參數(shù)
K = my_list()
print(K)
# 第二次調(diào)用參數(shù)
R = my_list()
print(R)
print('--------------------')
def my_list1(L = None):
    if L is None:
        L = []
    L.append('END')
    return L
# 第一次調(diào)用參數(shù)
K1 = my_list1()
print(K1)
# 第二次調(diào)用參數(shù)
R1 = my_list1()
print(R1)

輸出結(jié)果:

[1, 2, 3, 4, 5, 'END']
['END']
['END', 'END']
--------------------
['END']
['END']

以上就可以看到,如果定義函數(shù)時(shí),參數(shù)為list: L = [ ] 在多次使用默認(rèn)參數(shù)時(shí) 就會(huì)出現(xiàn) 重復(fù)添加的情況,原因也很簡(jiǎn)單,我們定義了一個(gè)默認(rèn)參數(shù)的值就會(huì)創(chuàng)建一個(gè)數(shù)據(jù)對(duì)象,函數(shù)執(zhí)行完返回的值會(huì)存儲(chǔ)在數(shù)據(jù)對(duì)象中,所以再次調(diào)用會(huì)呈現(xiàn)累加的情況,我們可以給參數(shù)定義一個(gè)None L = None 特殊的一個(gè)空對(duì)象(這個(gè)對(duì)象是不變的),這樣就不會(huì)造成累加的情況了。

可變參數(shù)

可變參數(shù)指?jìng)魅氲膮?shù)是可變的,不同于默認(rèn)參數(shù),可變參數(shù)可以理解為傳入一個(gè)list或tuple,具體的使用有兩種方式

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# 第一種 
def my_calc(numbers):
    sum = 0
    for n in numbers:
        sum = sum + n * n
    return sum
#傳入一個(gè)list
m = [1,2,3,4,5,6]
print(my_calc(m))
# 第二種
def my_calc1(*numbers):
    sum = 0
    for n in numbers:
        sum = sum + n * n
    return sum
# 直接將參數(shù)用逗號(hào)隔開,傳進(jìn)去
print(my_calc1(1,3,5,7,9))
# 接收一個(gè)list的寫法
n = [2,4,6,8,10]
print(my_calc1(*n))

輸出結(jié)果:

91
165
220

可以看出可變參數(shù)的寫法有兩種,一種是直接傳入一個(gè)list,第二種是用*numbers 直接將參數(shù)傳入,list 傳入時(shí)用 *n傳入。

關(guān)鍵字參數(shù)

關(guān)鍵字參數(shù)允許你傳入0個(gè)或任意個(gè)含參數(shù)名的參數(shù),這些關(guān)鍵字參數(shù)在函數(shù)內(nèi)部自動(dòng)組裝為一個(gè)dict。與java中傳入一個(gè)map 集合類似,如下:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
def person(name, age, **kw):
    print('name:', name, 'age:', age, 'other:', kw)
    return
# 通過name = value 形式傳入
person('張三', 35, weight=55,height = 175)
##直接傳入一個(gè)dict
others = {'weight': 65,'height': 185}

person ('李四',45,**others)

輸出結(jié)果:

name: 張三 age: 35 other: {'weight': 55, 'height': 175}
name: 李四 age: 45 other: {'weight': 65, 'height': 185}

最后**others傳入的是others 的復(fù)制版本,others 的變化不會(huì)引起函數(shù)的變化。

命名關(guān)鍵字參數(shù)

命名關(guān)鍵字是與位置參數(shù)比較的,位置可以靈活,寫法在位置參數(shù)前加一個(gè)可變參數(shù)*args 或者*,命名關(guān)鍵字參數(shù)也可以有默認(rèn)參數(shù),如下:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
def person(name, age, *,  weight,heigth):
    print('name=',name, 'age=',age,'weight=', weight,'heigth=', heigth)

person('張三', 24, weight=55, heigth=175)

def person(name, age, *args,  weight,heigth):
    print('name=',name, 'age=',age,'weight=', weight,'heigth=', heigth,args)

person('張三', 24,weight=55, heigth=175,*(1,2,3,4))

輸出結(jié)果:

name= 張三 age= 24 weight= 55 heigth= 175
name= 張三 age= 24 weight= 55 heigth= 175 (1, 2, 3)

組合參數(shù)

在Python中定義函數(shù),可以用必選參數(shù)、默認(rèn)參數(shù)、可變參數(shù)、關(guān)鍵字參數(shù)和命名關(guān)鍵字參數(shù),這5種參數(shù)都可以組合使用。但是他們是有順序的跟運(yùn)算符的級(jí)別一樣。順序如下:

  • 必選參數(shù)
  • 默認(rèn)參數(shù)
  • 可變參數(shù)
  • 命名關(guān)鍵字參數(shù)
  • 關(guān)鍵字參數(shù)

要注意的是不要同時(shí)使用太多的組合,否則函數(shù)接口的可理解性很差。

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
def f1(a, b, c=0, *args, **kw):
    print('a =', a, 'b =', b, 'c =', c, 'args =', args, 'kw =', kw)

args = (1, 2, 3, 4,5)
kw = {'d': 99, 'x': '#'}
f1(*args, **kw)

輸出結(jié)果:

a = 1 b = 2 c = 3 args = (4, 5) kw = {'d': 99, 'x': '#'}

不可思議吧,看到這個(gè)結(jié)果,對(duì)照組合參數(shù)的級(jí)別不難理解。參數(shù)到這就介紹完了,只有多實(shí)踐才能深入理解。

遞歸函數(shù)

遞歸函數(shù)在各種語言中都有,python的遞歸有啥特點(diǎn)呢?廖雪峰大神專門一節(jié)講解,我們就來看看吧。

遞歸函數(shù)的優(yōu)點(diǎn)是定義簡(jiǎn)單,邏輯清晰。理論上,所有的遞歸函數(shù)都可以寫成循環(huán)的方式,但循環(huán)的邏輯不如遞歸清晰。
遞歸函數(shù)的缺點(diǎn)是遞歸太深的話,因?yàn)閜ython沒有尾遞歸優(yōu)化會(huì)導(dǎo)致棧溢出。

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

#n! n的階乘
def fact(n):
    if n==1:
        return 1
    return n * fact(n - 1)
print(fact(10))
print(fact(20))

輸出結(jié)果:

3628800
2432902008176640000

參考

https://www.python.org
http://www.runoob.com/python3/python3-tutorial.html
https://www.liaoxuefeng.com

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 本文為《爬著學(xué)Python》系列第十篇文章。 在實(shí)際操作中,可能函數(shù)是我們幾乎唯一的實(shí)現(xiàn)操作的方式,這是因?yàn)楹瘮?shù)能...
    SyPy閱讀 5,705評(píng)論 0 8
  • Python 是一種相當(dāng)高級(jí)的語言,通過 Python 解釋器把符合語法的程序代碼轉(zhuǎn)換成 CPU 能夠執(zhí)行的機(jī)器碼...
    Python程序媛閱讀 2,031評(píng)論 0 3
  • 三年前的秋天,我從學(xué)校離開,進(jìn)入幼兒園學(xué)習(xí)。 幼兒園就如這副圖片一樣,綠色的草地宛如不小心闖進(jìn)了內(nèi)蒙古的大草原,心...
    海上日落閱讀 527評(píng)論 0 0
  • 這個(gè)時(shí)代布滿了黑暗。 那些企圖洗去歷史丑惡,借以開啟新時(shí)代的一批人,正在無情的壓制著持反對(duì)意見的人。 街上人潮狂奔...
    騎士日記閱讀 443評(píng)論 0 1
  • 文/ 謝友芝 圖/網(wǎng)絡(luò)(權(quán)侵刪) 昆明又下雨了 灰暗的天空 刺骨...
    小小逗號(hào)閱讀 176評(píng)論 0 0

友情鏈接更多精彩內(nèi)容