第三章 過程大于結(jié)果

3.1 懶人炒菜機(jī)

1. 函數(shù)是什么

函數(shù),英文Function,顧名思義函數(shù)就是一種功能,簡寫 f,將輸入的東西變?yōu)榱硪环N輸出 。
比如,人本來是沒穿衣服的,衣服可以讓人改變氣質(zhì),讓人變得不一樣。沒穿衣服的人就是輸入,衣服是Function,氣質(zhì)有所改變的人是輸出,這里的 f 就衣服;再比如機(jī)器貓里面看到的縮小燈,人本來是正常大小,通過縮小燈,可以變成矮小的人。正常大小的人就是輸入,縮小燈就是Function,矮小的人就是輸出。

縮小燈就是Function

數(shù)學(xué)上的函數(shù)代表了集合之間的對應(yīng)關(guān)系,如 f(x) = x2
而對于程序員來說,函數(shù)是一種語法結(jié)構(gòu),它將一些指令封裝打包在一起,形成一個實(shí)現(xiàn)某種功能的工具。輸入的數(shù)據(jù)叫做參數(shù),輸出的數(shù)據(jù)叫做返回值

2. 定義函數(shù)

Python中定義函數(shù)依靠關(guān)鍵字def,格式如下

def Function_Name(arg1,arg2,……):
    指令1(前面要有縮進(jìn))
    指令2(前面要有縮進(jìn))
    指令3(前面要有縮進(jìn))
    指令4(前面要有縮進(jìn))
          ……
     若有return語句,則程序只執(zhí)行到return語句

如,唱生日歌,每一個人生日都要唱生日歌,那么人名就是作為輸入,而輸出就是唱生日為該人慶祝。

"""
無定義函數(shù)時
給小明,小紅分別唱生日歌:
"""
print("Happy Birthday To You")
print("Happy Birthday To You")
print("Happy Birthday To You")
print("Happy Birthday To 小明")
print("Happy Birthday To You")

print("Happy Birthday To You")
print("Happy Birthday To You")
print("Happy Birthday To You")
print("Happy Birthday To 小紅")
print("Happy Birthday To You")

"""
重復(fù)的歌詞太多,我們可以定義函數(shù)裝起來
"""
def Birthday_Song(name):
    print("Happy Birthday To You")
    print("Happy Birthday To You")
    print("Happy Birthday To You")
    print("Happy Birthday To " + name)
    print("Happy Birthday To You")

Birthday_Song("小明")
Birthday_Song("小紅")

結(jié)果:
Happy Birthday To You
Happy Birthday To You
Happy Birthday To You
Happy Birthday To 小明
Happy Birthday To You
Happy Birthday To You
Happy Birthday To You
Happy Birthday To You
Happy Birthday To 小紅
Happy Birthday To You
----------------分割線:只執(zhí)行到return語句--------------------
def Birthday_Song(name):
    print("Happy Birthday To You")
    print("Happy Birthday To You")
    print("Happy Birthday To You")
    print("Happy Birthday To " + name)
    return print(name+" 生日快樂!")  """只執(zhí)行到return語句"""
    print("Happy Birthday To You")

Birthday_Song("小明")
結(jié)果:
Happy Birthday To You
Happy Birthday To You
Happy Birthday To You
Happy Birthday To 小明
小明 生日快樂!

3. 調(diào)用函數(shù)

就是使用那個函數(shù)的名字,然后若是有參數(shù),則輸入?yún)?shù)。

print()  """print()也是一個函數(shù)"""
print("這是參數(shù)")
結(jié)果:

這是參數(shù)

4.函數(shù)文檔

有時候如果對一個函數(shù)不知道它是用來干什么的,我們可以查看它的函數(shù)文檔。

方法1:使用help()函數(shù)查看函數(shù)文檔。如查看print函數(shù),記得要去掉括號
用help()函數(shù)查看print函數(shù)

方法2:使用 "?" 查看。記得去括號。
用 "?" 查看

3.2 參數(shù)傳遞

1. 基本傳參

  • 形式參數(shù):進(jìn)入函數(shù)所需要的參數(shù)。
  • 實(shí)際參數(shù):實(shí)際進(jìn)入函數(shù)的數(shù)據(jù)。
    形參與實(shí)參
    傳參:實(shí)際參數(shù)通過形式參數(shù),傳入到函數(shù)中。
    基本傳參
    1)通過位置傳參、2)通過關(guān)鍵字傳參、3)位置與關(guān)鍵字混用傳參
"""打印參數(shù)函數(shù)"""
def Print_args(a,b,c):
    print(a,b,c)

"""1)通過位置傳參"""
Print_args(1,2,3)
結(jié)果:1 2 3

"""2)通過關(guān)鍵字傳參"""
Print_args(c=3,b=2,a=1)
結(jié)果:1 2 3

"""3)位置與關(guān)鍵字混用傳參"""
Print_args(1,c=2,b=3)  結(jié)果:1 3 2
Print_args(a=1,b=2,3) """報錯"""
Print_args(3,b=2,a=1) """報錯"""

"""由此可見,盡量傳參盡量不要混合使用,一般使用位置傳參。"""

2. 包裹傳參

若函數(shù)需要多個參數(shù)時,我們可以使用包裹傳參。格式如下

"""參數(shù)以元組的形式裝入:包裹位置傳參"""
def function1(*args):   """ * 表示多個參數(shù)需要輸入"""
    語句……

"""參數(shù)以字典的形式裝入:包裹關(guān)鍵字傳參"""
def function2(**args):   """ ** 表示多個關(guān)鍵字和參數(shù)需要輸入"""
    語句……

1)包裹位置傳參、2)包裹關(guān)鍵字傳參、3)兩者混用

"""舉例"""
 """1)包裹位置傳參"""   
def Package_args_pos(*args):
    print(args)

Package_args_pos(1,3,4,5)
Package_args_pos(2,6,7,9,10,11)
結(jié)果:
(1, 3, 4, 5)
(2, 6, 7, 9, 10)
兩次調(diào)用的參數(shù)不一樣,但是由于包裹傳參,依舊可以進(jìn)行,
將這些參數(shù)按照順序收入到一個元組中,輸出的是一個包含參數(shù)的元組。

 """2)包裹關(guān)鍵字傳參"""  
def Package_args_keyw(**args):
    print(args)
    
Package_args_keyw(a=1,b=3) """關(guān)鍵字是a,b;值是1,3"""
Package_args_keyw(x=2,y=6,z=7) """關(guān)鍵字是x,y,z;值是2,6,7"""

結(jié)果:
{'a': 1, 'b': 3}
{'x': 2, 'y': 6, 'z': 7}
由于有關(guān)鍵字的存在,因此以字典的形式將參數(shù)裝入,
形成一個個鍵值對,最終以字典的形式輸出。

 """3)包裹關(guān)鍵字傳參"""  
def Package_args_mix(*args1,**args2):
    print(args1)
    print(args2)

Package_args_mix(1,3,5,a=2,b=4,c=4)
Package_args_mix(2,4,6,a=1,b=3,c=5)
結(jié)果:
(1, 3, 5)
{'a': 2, 'b': 4, 'c': 4}
(2, 4, 6)
{'a': 1, 'b': 3, 'c': 5}

3. 解包裹(unpacking)

將一個容器(元組、列表、字典)里面的各參數(shù)分解出來。

"""解元組"""
  方式(1)
Tuple = (1,3,4,5)
print(*Tuple)
結(jié)果:1 3 4 5

  方式(2)
def Unpacking(a,b,c):
  print(a,b,c)

Tuple = (1,3,4)
Unpacking(*Tuple)
結(jié)果:1 3 4

"""解列表"""
  方式(1)
List = [2,4,5,6]
print(*List)
結(jié)果:2 4 5 6

  方式(2)
def Unpacking(a,b,c):
  print(a,b,c)

List = [2,4,5,6]
Unpacking(*List)
結(jié)果:2 4 5

"""不能直接這樣解字典"""
Dict = {"a":1,"b":2,"c":3}
print(**Dict)
會報錯

  方式(2)
def Unpacking(a,b,c):
  print(a,b,c)

Dict = {"x":1,"y":2,"z":3}
Unpacking(**Dict)  """有兩個*號"""
結(jié)果:1 2 3

"""
無論是元組、字典、列表方式(2)解包裹,只有參數(shù)個數(shù)與容器元素個數(shù)一樣時才可以使用。
"""

3.3 遞歸

1.高斯求和

遞歸的兩種方式
我們一般情況下討論的遞歸指函數(shù)對本身的調(diào)用。
遞歸會一直調(diào)用本身,所以我們需要一個遞歸出口使其結(jié)束。
我們可以想象遞歸相當(dāng)于"俄羅斯套娃",不斷重復(fù)著同樣的娃娃,而遞歸出口就是當(dāng)娃娃最小時,就不再繼續(xù)重新返回,將套娃裝好。
俄羅斯套娃

下面舉一個高斯求和的例子來說明。
現(xiàn)在要求1到100的和,除了循環(huán)外,我們還可以使用遞歸。

"""定一個求和函數(shù)"""
def gauss_Sum(n):  """n指的是從1加到n"""
      if  n == 1:   """遞歸出口,當(dāng)加的數(shù)為1的時候,就重新套回去"""
            return 1;
      else:
            return n + gauss_Sum(n - 1)  """不然就是n + (n-1)"""

print(gauss_Sum(100))
結(jié)果:5050

2.函數(shù)棧(Stack)

棧是一種數(shù)據(jù)結(jié)構(gòu),棧中的元素叫,幀按照"先進(jìn)后出"的規(guī)則進(jìn)出棧。
1)壓棧(push)
當(dāng)有新的元素進(jìn)入棧時,用push把元素壓入棧,而舊的元素也會被擠到下方。

push

2)彈棧(pop)

當(dāng)有元素出棧時,用pop把元素彈出棧,剩余元素也會被彈起,但不會彈出棧。
pop

先進(jìn)后出
push and pop

3.變量的作用域

1)局部變量
函數(shù)內(nèi)部定義的變量。不同的函數(shù),可以定義相同的名字的局部變量,但是各用個的不會產(chǎn)生影響。局部變量的作用,為了臨時保存數(shù)據(jù)需要在函數(shù)中定義變量來進(jìn)行存儲。
2)全局變量
定義在.py模塊(相當(dāng)于主程序main())內(nèi)部,作用在整個.py模塊。生命周期:從變量被創(chuàng)造開始到.py模塊結(jié)束死亡。

A = 100 """ 全局變量 """
def fun():
    a = 10 """ 局部變量 """
    return a + 100
print(A)  """ 可以正常輸出全局變量的值"""
 """ print(a) 出現(xiàn)錯誤: name 'a' is not defined 
試圖在函數(shù)體外獲取一個局部變量的值不行"""

結(jié)果:100
num = 0

def Demo1():
    num = 1
    print("在demo1中的結(jié)果:",num)

def Demo2():

    print("在demo2中的結(jié)果:",num)

Demo1()
Demo2()

print("在函數(shù)外面中的結(jié)果:",num)

結(jié)果:
在demo1中的結(jié)果: 1
在demo2中的結(jié)果: 0
在函數(shù)外面中的結(jié)果: 0
分析:
從結(jié)果可以看出,我們在demo1中num = 1,只在demo1內(nèi)部起作用,而全局變量num仍然是0;
因?yàn)樵趐ython中,在函數(shù)內(nèi)部改變?nèi)肿兞康闹?,會默認(rèn)的在函數(shù)內(nèi)部創(chuàng)建一個新的變量,
全局變量并沒有改變。要想要改變?nèi)肿兞康闹担枰诤瘮?shù)內(nèi)部用global聲明。
-------------分割線------------------
num = 0

def Demo1():
    global num
    num = 1
    print("在demo1中的結(jié)果:",num)

def Demo2():

    print("在demo2中的結(jié)果:",num)

Demo1()
Demo2()

print("在函數(shù)外面中的結(jié)果:",num)
""'
運(yùn)行結(jié)果為:
在demo1中的結(jié)果: 1
在demo2中的結(jié)果: 1
在函數(shù)外面中的結(jié)果: 1
"""

3.4 引入那把寶劍

1.引入模塊

導(dǎo)入第三方模塊的三種方式
1)import 函數(shù)庫名

"""導(dǎo)入烏龜畫圖庫"""
import turtle

2)import 函數(shù)庫名 as 簡稱

"""導(dǎo)入烏龜畫圖庫"""
import turtle as t

3)from 函數(shù)庫名 import 函數(shù)

"""導(dǎo)入烏龜畫圖庫里的所有函數(shù)"""
from turtle import *
"""導(dǎo)入烏龜畫圖庫里的某個函數(shù)"""
from turtle import fillcolor

3.5 異常處理

1.bug

bug意為蟲子,也指程序中出現(xiàn)的錯誤
1)語法錯誤:這種錯誤通常編譯器會幫你找出。

for i in range(10)
        print(i)
將不執(zhí)行代碼,因?yàn)閒or()后面沒有加冒號:

for i in range(10):
print(i)
將不執(zhí)行代碼,因?yàn)闆]有縮進(jìn)

a = [1,2,3]
print(a[3])
錯誤,下標(biāo)越界錯誤。

2)語義錯誤:這種錯誤比較隱蔽,不易發(fā)現(xiàn)。

想要獲得一個后面有小數(shù)點(diǎn)的數(shù)字,但是會發(fā)現(xiàn)輸出的是整數(shù)。
def average(x, y):
     return x + y / 2
print(average(1,2)) 
預(yù)期結(jié)果:1.5
實(shí)際結(jié)果:2.0
因?yàn)镻ython自動將其認(rèn)為是整型的,故自動向上取整。

3)異常

1 / 0
Traceback (most recent call last):
  File "<input>", line 1, in <module>  # 異常信息所在位置
ZeroDivisionError: division by zero  # 異常類型及引起原因

2.Debug

寫完代碼后,對代碼進(jìn)行調(diào)試、排除錯誤異常的過程。

3.異常處理

對于比較可能出現(xiàn)錯誤的代碼,可以在這些代碼之前做一些處理。這樣既可以使得程序結(jié)束前進(jìn)行更多的操作,如獲取關(guān)于錯誤的信息,幫助Debug;還可以讓程序在犯錯后依舊走下去。
異常處理的語句如下:

try:
     ……
except exception1 as e1 :
     ……
except exception2 as e2:
     ……若語句錯誤則捕獲異常
else:
     ……沒有異常發(fā)生時執(zhí)行else子句。
finally:
     ……不管有沒有異常發(fā)生最終都執(zhí)行finally子句。

以上是自動拋出異常,對于無法自動拋出的異常。我們可以手動拋出。使用關(guān)鍵字raise。

raise Exception

舉例

try:
    x = int(input("輸入整數(shù):"))
    y = int(input("輸入整數(shù):"))
    if y == 0:
        raise Exception("主動拋出ZeroDivisionError")
    print(x / y)
except NameError as e:
    print("Error:",e)
except ValueError as e:
    print("Error:",e)
else:
    print("沒有異常發(fā)生時執(zhí)行")
finally:
    print("有無異常發(fā)生均執(zhí)行")
    
結(jié)果1:
輸入整數(shù):10
輸入整數(shù):0
有無異常發(fā)生均執(zhí)行
Traceback (most recent call last):
Exception: 主動拋出ZeroDivisionError

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

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

  • 3.1 懶人炒菜機(jī) 3.1.1 函數(shù)是什么 集合的對應(yīng)關(guān)系 數(shù)據(jù)轉(zhuǎn)換的魔法盒子 語句的封裝。輸入數(shù)據(jù)被稱為參數(shù),參...
    SibyLtuI閱讀 435評論 0 0
  • 3.1 懶人炒菜機(jī) 1.何為函數(shù) 函數(shù)(Function)在數(shù)學(xué)上的定義是指集合之間的對應(yīng)關(guān)系。從數(shù)據(jù)的角度,函數(shù)...
    塵濯閱讀 778評論 0 3
  • 3.1懶人炒菜機(jī) 1.函數(shù) 三種看待函數(shù)的方式:集合的對應(yīng)關(guān)系、數(shù)據(jù)的魔法盒子(數(shù)據(jù)轉(zhuǎn)換)、語句的封裝 2.定義函...
    lammmya閱讀 304評論 0 0
  • 每一次迎來新的一年,我都會在心里祈禱,真希望這輩子所有糟糕的事在過去的歲月里都發(fā)生完了。 一直都想著寫一篇關(guān)于老幺...
    羥羊閱讀 236評論 0 2
  • .春分逢雪有感 文/梅香芳塵 雪入春分景色稀 滿坡金盞隱芳菲 松枝柏骨猶含笑 溪畔垂楊待綠歸 ——2019-3-21
    梅香芳塵閱讀 134評論 0 1

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