目錄
- 1. 函數介紹
- 2. 函數的參數
- 3. 模塊與函數
- 4. 遞歸函數
- 5. 匿名函數
- 6. 多返回值
python 的學習已經進入到第四天,前面幾章我們已經學會了基本的變量操作,以及分支結構和循環結構,那么本章,我們來說說 python 中的函數
1. 函數介紹
在開發程序中,如果需要調用某段代碼多次,但是為了 提高編寫的效率以及代碼的可重用性,所以把具有獨立功能的代碼塊 組織成一個獨立的小模塊,這就是函數。
在Python 中可以使用
def
關鍵字來定義函數,和變量一樣每個函數也需要聲明一個符合命名規范的名稱。在函數后面的圓括號內可以放置我們需要傳遞的參數,待結果執行完畢我們也可以根據需要 使用
return
關鍵字返回調用結果。
?
案例:
我們先看一道數學題
事實上,上面的問題等同于將8個蘋果分成四組每組至少一個蘋果有多少種方案。想到這一點問題的答案就呼之欲出了。
如果我們還沒有學過函數,我們可以這么寫
"""
輸入M和N 計算C(M,N)
version:0.1
author:coke
"""
m = int(input('m='))
n = int(input('n='))
fm = 1
for x in range(1,m + 1):
fm *= x
fn = 1
for y in range(1,n + 1):
fn *= y
fmn = 1
for z in range(1,m - n + 1):
fmn *= z
print(fm // fn // fmn)
?
你應該發現了,相似的for循環我們寫了三遍,我們是不是可以做一個提取呢?
"""
用函數求分配方案
version: 0.1
author: coke
"""
#-*- coding:utf-8 -*-
def factorial(num):
"""
求階乘
:param num 非負整數
:return num的階乘
"""
result = 1
for n in range(1, num + 1):
result *= n
return result
m = int(input("請輸入一個數字m:"))
n = int(input("請輸入一個數字n:"))
print(factorial(m)//factorial(n)//factorial(m-n))
?
2. 函數的參數
函數是絕大多數編程語言中都支持的一個代碼的“構建塊”,但是Python中的函數與其他語言中的函數還是有很多不太相同的地方,其中一個顯著的區別就是Python對函數參數的處理。在Python中,函數的參數可以有默認值,也支持使用可變參數,所以Python并不需要像其他語言一樣支持函數的重載 。所以我們定義一個函數時,可以讓它有很多不同的使用方式.
from random import randint
def roll_rice(n = 2):
"""
:param n:色子數
:return: n顆色子的點數和
"""
total = 0
for _ in range(n):
total += randint(1,6)
return total
def add(a ,b = 0 ,c=0):
return a + b + c
print(roll_rice(1))
print(roll_rice(1))
print(roll_rice(2))
print(roll_rice(2))
# 傳遞參數時可以不按照設定的順序進行傳遞
print(add(c=50, a=100, b=200))
我們給上面兩個函數的參數都設定了默認值,這也就意味著如果在調用函數的時候如果沒有傳入對應參數的值時將使用該參數的默認值,所以在上面的代碼中我們可以用各種不同的方式去調用
add
函數,這跟其他很多語言中函數重載的效果是一致的。
其實上面的add 函數還有更好的實現方法,因為我們可能會 對 0個或多個參數進行加法運算,而具體有幾個參數完全可以由調用者決定
#-*-coding:utf-8-*-
# 在參數名前面的*表示args是一個可變參數
# 即在調用add函數時可以傳入0個或多個參數
def add(*args):
total = 0
argsType = type(args)
print("args的類型為:%s"%argsType)
for val in args:
total += val
return total
print(add())
print(add(1))
print(add(1,2))
print(add(1,2,3))
?
3. 模塊與函數
對于任何一種編程語言來說,給變量、函數這樣的標識符起名字都是一個讓人頭疼的問題,因為我們會遇到命名沖突這種尷尬的情況。最簡單的場景就是在同一個.py文件中定義了兩個同名函數,由于Python沒有函數重載的概念,那么后面的定義會覆蓋之前的定義,也就意味著兩個函數同名函數實際上只有一個是存在的。
"""
測試代碼
version:0.1
author:coke
"""
def foo():
print("hello-world")
def foo():
print("world-hello")
#下面的代碼會輸出什么? 是不是有點混亂
foo()
?
當然上面的這種情況我們很容易就能避免,但是如果項目是由多人協作進行團隊開發的時候,團隊中可能有多個程序員都定義了名為
foo
的函數,那么怎么解決這種命名沖突呢?答案其實很簡單,Python中每個文件就代表了一個模塊(module),我們在不同的模塊中可以有同名的函數,在使用函數的時候我們通過
import
關鍵字導入指定的模塊就可以區分到底要使用的是哪個模塊中的
foo
函數,代碼如下所示
module1.py
def foo():
print("hello-world")
module2.py
def foo():
print("world-hello")
moduleTest1.py
import module1 as m1
import module2 as m2
#輸出 hello-world
m1.foo()
#輸出 world-hello
m2.foo()
?
但是如果將代碼寫成了下面的樣子,那么程序中調用的是最后導入的那個
foo
,因為后導入的foo覆蓋了之前導入的
foo
。
moduleTest2.py
from module1 import foo
from module2 import foo
# 輸出goodbye, world!
foo()
?
需要說明的是,如果我們導入的模塊除了定義函數之外還中有可以執行代碼,那么Python解釋器在導入這個模塊時就會執行這些代碼,事實上我們可能并不希望如此,因此如果我們在模塊中編寫了執行代碼,最好是將這些執行代碼放入如下所示的條件中,這樣的話除非直接運行該模塊,if條件下的這些代碼是不會執行的,因為只有直接執行的模塊的名字才是
'__main__'
。
def foo():
pass
def bar():
pass
# _name_ 是Python中一個隱含的變量它代表了模塊的名字
# 只有被python解釋器直接執行的模塊的名字是 __main__
if __name__ == '__main__':
print('call foo')
foo()
print("call bar")
bar
?
4. 遞歸函數
遞歸函數: 如果一個函數在內部不調用其它的函數,而是自己本身的話,這個函數就是遞歸函數。
?
舉個例子:我們來計算階乘?
n! = 1 * 2 * 3 * ... * n
方案1: 循環解決
"""
while 循環算階乘
version:0.1
author:coke
"""
# -*- coding:utf-8 -*-
def calNum(num):
i = 1
result = 1
while i <= num:
result *= i
i += 1
return result
total = calNum(4)
print(total)
?
方案2: 遞歸函數
"""
while 循環算階乘
version:0.1
author:coke
"""
# -*- coding:utf-8 -*-
def calNum(num):
if num > 1:
result = num * calNum(num - 1)
else:
result = 1
return result
total = calNum(4)
print(total)
?
5. 匿名函數
用
lambda
關鍵詞能創建小型匿名函數。這種函數得名于省略了用
def
聲明函數的標準步驟。
lambda
函數的語法只包含一個語句,如下:
lambda [arg1 [,arg2,.....argn]]:expression
?
1. 使用匿名函數求兩數之和 (自己定義函數 )
"""
匿名函數測試
version:0.1
author:coke
"""
def add(a,b):
return a+b
result1 = add(1,6)
# 使用lambda 表達式
sum = lambda x,y: x+y
result2 = sum(1,6)
print(result1)
print(result2)
?
2. 數據排序 (作為內置函數的參數 )
"""
匿名函數作為內置函數進行排序
關于 字典和列表的知識點后面會講
version:0.1
author:coke
"""
stus = [
{"name":"zhangsan", "age":18},
{"name":"lisi", "age":19},
{"name":"wangwu", "age":17}
]
stus.sort(key = lambda x:x['name'])
print(stus)
?
6. 多返回值
在python中 一個函數可不可以返回多個 返回值呢?
"""
多返回值的測試
version:0.1
author:coke
"""
def cal(a,b):
add = a+b
mul = a*b
return add,mul
result = cal(2,3)
print(result)
輸出結果
?
一個函數,返回多個返回值 ,本質上是利用了元組的特性。
注:關于元組,列表,字典的知識點后面會講,這里先提一嘴。
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
