溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

怎么使用Python函數(shù)和模塊

發(fā)布時(shí)間:2021-11-01 16:04:20 來(lái)源:億速云 閱讀:144 作者:iii 欄目:編程語(yǔ)言

本篇內(nèi)容介紹了“怎么使用Python函數(shù)和模塊”的有關(guān)知識(shí),在實(shí)際案例的操作過(guò)程中,不少人都會(huì)遇到這樣的困境,接下來(lái)就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

在講解本章節(jié)的內(nèi)容之前,我們先來(lái)研究一道數(shù)學(xué)題,請(qǐng)說(shuō)出下面的方程有多少組正整數(shù)解。

怎么使用Python函數(shù)和模塊

你可能已經(jīng)想到了,這個(gè)問(wèn)題其實(shí)等同于將8個(gè)蘋(píng)果分成四組且每組至少一個(gè)蘋(píng)果有多少種方案,因此該問(wèn)題還可以進(jìn)一步等價(jià)于在分隔8個(gè)蘋(píng)果的7個(gè)空隙之間插入三個(gè)隔板將蘋(píng)果分成四組有多少種方案,也就是從7個(gè)空隙選出3個(gè)空隙放入隔板的組合數(shù),所以答案是

怎么使用Python函數(shù)和模塊

組合數(shù)的計(jì)算公式如下所示:

怎么使用Python函數(shù)和模塊

根據(jù)我們前面學(xué)習(xí)的知識(shí),可以用循環(huán)做累乘來(lái)計(jì)算階乘,那么通過(guò)下面的Python代碼我們就可以計(jì)算出組合數(shù)

怎么使用Python函數(shù)和模塊

的值,代碼如下所示:

"""
輸入M和N計(jì)算C(M,N)

Version: 0.1
Author: 駱昊
"""
m = int(input('m = '))
n = int(input('n = '))
# 計(jì)算m的階乘
fm = 1
for num in range(1, m + 1):
   fm *= num
# 計(jì)算n的階乘
fn = 1
for num in range(1, n + 1):
   fn *= num
# 計(jì)算m-n的階乘
fm_n = 1
for num in range(1, m - n + 1):
   fm_n *= num
# 計(jì)算C(M,N)的值
print(fm // fn // fm_n)

函數(shù)的作用

不知大家是否注意到,上面的代碼中我們做了三次求階乘,雖然m、n、m - n的值各不相同,但是三段代碼并沒(méi)有實(shí)質(zhì)性的區(qū)別,屬于重復(fù)代碼。世界級(jí)的編程大師Martin Fowler先生曾經(jīng)說(shuō)過(guò):“代碼有很多種壞味道,重復(fù)是最壞的一種!”。要寫(xiě)出高質(zhì)量的代碼首先要解決的就是重復(fù)代碼的問(wèn)題。對(duì)于上面的代碼來(lái)說(shuō),我們可以將計(jì)算階乘的功能封裝到一個(gè)稱(chēng)為“函數(shù)”的代碼塊中,在需要計(jì)算階乘的地方,我們只需要“調(diào)用函數(shù)”就可以了。

定義函數(shù)

怎么使用Python函數(shù)和模塊

在Python中可以使用def關(guān)鍵字來(lái)定義函數(shù),和變量一樣每個(gè)函數(shù)也應(yīng)該有一個(gè)漂亮的名字,命名規(guī)則跟變量的命名規(guī)則是一致的。在函數(shù)名后面的圓括號(hào)中可以放置傳遞給函數(shù)的參數(shù),就是我們剛才說(shuō)到的函數(shù)的自變量,而函數(shù)執(zhí)行完成后我們會(huì)通過(guò)return關(guān)鍵字來(lái)返回函數(shù)的執(zhí)行結(jié)果,就是我們剛才說(shuō)的函數(shù)的因變量。一個(gè)函數(shù)要執(zhí)行的代碼塊(要做的事情)也是通過(guò)縮進(jìn)的方式來(lái)表示的,跟之前分支和循環(huán)結(jié)構(gòu)的代碼塊是一樣的。大家不要忘了def那一行的最后面還有一個(gè):,之前提醒過(guò)大家,那是在英文輸入法狀態(tài)下輸入的冒號(hào)。

我們可以通過(guò)函數(shù)對(duì)上面的代碼進(jìn)行重構(gòu)。所謂重構(gòu),是在不影響代碼執(zhí)行結(jié)果的前提下對(duì)代碼的結(jié)構(gòu)進(jìn)行調(diào)整。重構(gòu)之后的代碼如下所示。

"""
輸入M和N計(jì)算C(M,N)

Version: 0.1
Author: 駱昊
"""# 定義函數(shù):def是定義函數(shù)的關(guān)鍵字、fac是函數(shù)名,num是參數(shù)(自變量)
def fac(num):
   """求階乘"""
   result = 1
   for n in range(1, num + 1):
       result *= n
   # 返回num的階乘(因變量)
   return result m = int(input('m = '))
n = int(input('n = '))
# 當(dāng)需要計(jì)算階乘的時(shí)候不用再寫(xiě)重復(fù)代碼而是直接調(diào)用函數(shù)fac
# 調(diào)用函數(shù)的語(yǔ)法是在函數(shù)名后面跟上圓括號(hào)并傳入?yún)?shù)
print(fac(m) // fac(n) // fac(m - n))

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

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

如果函數(shù)中沒(méi)有return語(yǔ)句,那么函數(shù)默認(rèn)返回代表空值的None。另外,在定義函數(shù)時(shí),函數(shù)也可以沒(méi)有自變量,但是函數(shù)名后面的圓括號(hào)是必須有的。Python中還允許函數(shù)的參數(shù)擁有默認(rèn)值,我們可以把上一課“CRAPSdubo游戲”的搖篩子獲得點(diǎn)數(shù)的功能封裝成函數(shù),代碼如下所示。

"""
參數(shù)的默認(rèn)值1

Version: 0.1
Author: 駱昊
"""
from random import randint# 定義搖篩子的函數(shù),n表示篩子的個(gè)數(shù),默認(rèn)值為2
def roll_dice(n=2):
   """搖篩子返回總的點(diǎn)數(shù)"""
   total = 0
   for _ in range(n):
       total += randint(1, 6)
   return total# 如果沒(méi)有指定參數(shù),那么n使用默認(rèn)值2,表示搖兩顆篩子
print(roll_dice())
# 傳入?yún)?shù)3,變量n被賦值為3,表示搖三顆篩子獲得點(diǎn)數(shù)
print(roll_dice(3))

我們?cè)賮?lái)看一個(gè)更為簡(jiǎn)單的例子。

"""
參數(shù)的默認(rèn)值2

Version: 0.1
Author: 駱昊
"""def add(a=0, b=0, c=0):
   """三個(gè)數(shù)相加求和"""
   return a + b + c# 調(diào)用add函數(shù),沒(méi)有傳入?yún)?shù),那么a、b、c都使用默認(rèn)值0
print(add())         # 0
# 調(diào)用add函數(shù),傳入一個(gè)參數(shù),那么該參數(shù)賦值給變量a, 變量b和c使用默認(rèn)值0
print(add(1))        # 1
# 調(diào)用add函數(shù),傳入兩個(gè)參數(shù),1和2分別賦值給變量a和b,變量c使用默認(rèn)值0
print(add(1, 2))     # 3
# 調(diào)用add函數(shù),傳入三個(gè)參數(shù),分別賦值給a、b、c三個(gè)變量
print(add(1, 2, 3))  # 6
# 傳遞參數(shù)時(shí)可以不按照設(shè)定的順序進(jìn)行傳遞,但是要用“參數(shù)名=參數(shù)值”的形式
print(add(c=50, a=100, b=200))    # 350

注意:帶默認(rèn)值的參數(shù)必須放在不帶默認(rèn)值的參數(shù)之后,否則將產(chǎn)生SyntaxError錯(cuò)誤,錯(cuò)誤消息是:non-default argument follows default argument,翻譯成中文的意思是“沒(méi)有默認(rèn)值的參數(shù)放在了帶默認(rèn)值的參數(shù)后面”。

可變參數(shù)

接下來(lái),我們還可以實(shí)現(xiàn)一個(gè)對(duì)任意多個(gè)數(shù)求和的add函數(shù),因?yàn)镻ython語(yǔ)言中的函數(shù)可以通過(guò)星號(hào)表達(dá)式語(yǔ)法來(lái)支持可變參數(shù)。所謂可變參數(shù)指的是在調(diào)用函數(shù)時(shí),可以向函數(shù)傳入0個(gè)或任意多個(gè)參數(shù)。將來(lái)我們以團(tuán)隊(duì)協(xié)作的方式開(kāi)發(fā)商業(yè)項(xiàng)目時(shí),很有可能要設(shè)計(jì)函數(shù)給其他人使用,但有的時(shí)候我們并不知道函數(shù)的調(diào)用者會(huì)向該函數(shù)傳入多少個(gè)參數(shù),這個(gè)時(shí)候可變參數(shù)就可以派上用場(chǎng)。下面的代碼演示了用可變參數(shù)實(shí)現(xiàn)對(duì)任意多個(gè)數(shù)求和的add函數(shù)。

"""
可變參數(shù)

Version: 0.1
Author: 駱昊
"""# 用星號(hào)表達(dá)式來(lái)表示args可以接收0個(gè)或任意多個(gè)參數(shù)
def add(*args):
   total = 0
   # 可變參數(shù)可以放在for循環(huán)中取出每個(gè)參數(shù)的值
   for val in args:
       total += val
   return total# 在調(diào)用add函數(shù)時(shí)可以傳入0個(gè)或任意多個(gè)參數(shù)
print(add())
print(add(1))
print(add(1, 2))
print(add(1, 2, 3))
print(add(1, 3, 5, 7, 9))

用模塊管理函數(shù)

不管用什么樣的編程語(yǔ)言來(lái)寫(xiě)代碼,給變量、函數(shù)起名字都是一個(gè)讓人頭疼的問(wèn)題,因?yàn)槲覀儠?huì)遇到命名沖突這種尷尬的情況。最簡(jiǎn)單的場(chǎng)景就是在同一個(gè).py文件中定義了兩個(gè)同名的函數(shù),如下所示。

def foo():
   print('hello, world!')def foo():
   print('goodbye, world!') foo()    # 大家猜猜調(diào)用foo函數(shù)會(huì)輸出什么

當(dāng)然上面的這種情況我們很容易就能避免,但是如果項(xiàng)目是團(tuán)隊(duì)協(xié)作多人開(kāi)發(fā)的時(shí)候,團(tuán)隊(duì)中可能有多個(gè)程序員都定義了名為foo的函數(shù),這種情況下怎么解決命名沖突呢?答案其實(shí)很簡(jiǎn)單,Python中每個(gè)文件就代表了一個(gè)模塊(module),我們?cè)诓煌哪K中可以有同名的函數(shù),在使用函數(shù)的時(shí)候我們通過(guò)import關(guān)鍵字導(dǎo)入指定的模塊再使用完全限定名的調(diào)用方式就可以區(qū)分到底要使用的是哪個(gè)模塊中的foo函數(shù),代碼如下所示。

module1.py

def foo():
   print('hello, world!')

module2.py

def foo():
   print('goodbye, world!')

test.py

import module1
import module2

# 用“模塊名.函數(shù)名”的方式(完全限定名)調(diào)用函數(shù),
module1.foo()    # hello, world!
module2.foo()    # goodbye, world!

在導(dǎo)入模塊時(shí),還可以使用as關(guān)鍵字對(duì)模塊進(jìn)行別名,這樣我們可以使用更為簡(jiǎn)短的完全限定名。

test.py

import module1 
as m1
import module2 as m2

m1.foo()    # hello, world!
m2.foo()    # goodbye, world!

上面的代碼我們導(dǎo)入了定義函數(shù)的模塊,我們也可以使用from...import...語(yǔ)法從模塊中直接導(dǎo)入需要使用的函數(shù),代碼如下所示。

test.py

from module1 
import foo

foo()    # hello, world!

from module2 import foo

foo()    # goodbye, world!

但是,如果我們?nèi)绻麖膬蓚€(gè)不同的模塊中導(dǎo)入了同名的函數(shù),后導(dǎo)入的函數(shù)會(huì)覆蓋掉先前的導(dǎo)入,就像下面的代碼中,調(diào)用foo會(huì)輸出hello, world!,因?yàn)槲覀兿葘?dǎo)入了module2的foo,后導(dǎo)入了module1的foo 。如果兩個(gè)from...import...反過(guò)來(lái)寫(xiě),就是另外一番光景了。

test.py

from module2 
import foo
from module1 import foo

foo()    # hello, world!

如果想在上面的代碼中同時(shí)使用來(lái)自?xún)蓚€(gè)模塊中的foo函數(shù)也是有辦法的,大家可能已經(jīng)猜到了,還是用as關(guān)鍵字對(duì)導(dǎo)入的函數(shù)進(jìn)行別名,代碼如下所示。

test.py

from module1 
import foo 
as f1
from module2 import foo as f2

f1()    # hello, world!
f2()    # goodbye, world!

標(biāo)準(zhǔn)庫(kù)中的模塊和函數(shù)

Python標(biāo)準(zhǔn)庫(kù)中提供了大量的模塊和函數(shù)來(lái)簡(jiǎn)化我們的開(kāi)發(fā)工作,我們之前用過(guò)的random模塊就為我們提供了生成隨機(jī)數(shù)和進(jìn)行隨機(jī)抽樣的函數(shù);而time模塊則提供了和時(shí)間操作相關(guān)的函數(shù);上面求階乘的函數(shù)在Python標(biāo)準(zhǔn)庫(kù)中的math模塊中已經(jīng)有了,實(shí)際開(kāi)發(fā)中并不需要我們自己編寫(xiě),而math模塊中還包括了計(jì)算正弦、余弦、指數(shù)、對(duì)數(shù)等一系列的數(shù)學(xué)函數(shù)。隨著我們進(jìn)一步的學(xué)習(xí)Python編程知識(shí),我們還會(huì)用到更多的模塊和函數(shù)。

Python標(biāo)準(zhǔn)庫(kù)中還有一類(lèi)函數(shù)是不需要import就能夠直接使用的,我們將其稱(chēng)之為內(nèi)置函數(shù),這些內(nèi)置函數(shù)都是很有用也是最常用的,下面的表格列出了一部分的內(nèi)置函數(shù)。

怎么使用Python函數(shù)和模塊

“怎么使用Python函數(shù)和模塊”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI