目標(biāo)
- 函數(shù)的快速體驗
- 函數(shù)的基本使用
- 函數(shù)的參數(shù)
- 函數(shù)的返回值
- 函數(shù)的嵌套調(diào)用
- 在模塊中定義函數(shù)
01. 函數(shù)的快速體驗
1.1 快速體驗
- 所謂函數(shù),就是把 具有獨(dú)立功能的代碼塊 組織為一個小模塊懒鉴,在需要的時候 調(diào)用
- 函數(shù)的使用包含兩個步驟:
- 定義函數(shù) —— 封裝 獨(dú)立的功能
- 調(diào)用函數(shù) —— 享受 封裝 的成果
- 函數(shù)的作用屈嗤,在開發(fā)程序時彭谁,使用函數(shù)可以提高編寫的效率以及代碼的 重用
演練步驟
- 新建
04_函數(shù)
項目 - 復(fù)制之前完成的 乘法表 文件
- 修改文件,增加函數(shù)定義
multiple_table():
- 新建另外一個文件隶校,使用
import
導(dǎo)入并且調(diào)用函數(shù)
02. 函數(shù)基本使用
2.1 函數(shù)的定義
定義函數(shù)的格式如下:
def 函數(shù)名():
函數(shù)封裝的代碼
……
-
def
是英文define
的縮寫 - 函數(shù)名稱 應(yīng)該能夠表達(dá) 函數(shù)封裝代碼 的功能唆缴,方便后續(xù)的調(diào)用
-
函數(shù)名稱 的命名應(yīng)該 符合 標(biāo)識符的命名規(guī)則
- 可以由 字母锤躁、下劃線 和 數(shù)字 組成
- 不能以數(shù)字開頭
- 不能與關(guān)鍵字重名
2.2 函數(shù)調(diào)用
調(diào)用函數(shù)很簡單的蹲堂,通過函數(shù)名()
即可完成對函數(shù)的調(diào)用
2.3 第一個函數(shù)演練
需求
- 編寫一個打招呼
say_hello
的函數(shù)狼讨,封裝三行打招呼的代碼
- 編寫一個打招呼
- 在函數(shù)下方調(diào)用打招呼的代碼
name = "小明"
# 解釋器知道這里定義了一個函數(shù)
def say_hello():
print("hello 1")
print("hello 2")
print("hello 3")
print(name)
# 只有在調(diào)用函數(shù)時,之前定義的函數(shù)才會被執(zhí)行
# 函數(shù)執(zhí)行完成之后柒竞,會重新回到之前的程序中政供,繼續(xù)執(zhí)行后續(xù)的代碼
say_hello()
print(name)
用 單步執(zhí)行 F8 和 F7 觀察以下代碼的執(zhí)行過程
- 定義好函數(shù)之后,只表示這個函數(shù)封裝了一段代碼而已
- 如果不主動調(diào)用函數(shù)朽基,函數(shù)是不會主動執(zhí)行的
思考
- 能否將 函數(shù)調(diào)用 放在 函數(shù)定義 的上方布隔?
- 不能!
- 因為在 使用函數(shù)名 調(diào)用函數(shù)之前稼虎,必須要保證
Python
已經(jīng)知道函數(shù)的存在 - 否則控制臺會提示
NameError: name 'say_hello' is not defined
(名稱錯誤:say_hello 這個名字沒有被定義)
2.4 PyCharm 的調(diào)試工具
- F8 Step Over 可以單步執(zhí)行代碼衅檀,會把函數(shù)調(diào)用看作是一行代碼直接執(zhí)行
- F7 Step Into 可以單步執(zhí)行代碼,如果是函數(shù)霎俩,會進(jìn)入函數(shù)內(nèi)部
2.5 函數(shù)的文檔注釋
- 在開發(fā)中哀军,如果希望給函數(shù)添加注釋,應(yīng)該在 定義函數(shù) 的下方打却,使用 連續(xù)的三對引號
- 在 連續(xù)的三對引號 之間編寫對函數(shù)的說明文字
- 在 函數(shù)調(diào)用 位置杉适,使用快捷鍵
CTRL + Q
可以查看函數(shù)的說明信息
注意:因為 函數(shù)體相對比較獨(dú)立,函數(shù)定義的上方柳击,應(yīng)該和其他代碼(包括注釋)保留 兩個空行
03. 函數(shù)的參數(shù)
演練需求
- 開發(fā)一個
sum_2_num
的函數(shù) - 函數(shù)能夠?qū)崿F(xiàn) 兩個數(shù)字的求和 功能
演練代碼如下:
def sum_2_num():
num1 = 10
num2 = 20
result = num1 + num2
print("%d + %d = %d" % (num1, num2, result))
sum_2_num()
思考一下存在什么問題
函數(shù)只能處理 固定數(shù)值 的相加
如何解決猿推?
- 如果能夠把需要計算的數(shù)字,在調(diào)用函數(shù)時捌肴,傳遞到函數(shù)內(nèi)部就好了蹬叭!
3.1 函數(shù)參數(shù)的使用
- 在函數(shù)名的后面的小括號內(nèi)部填寫 參數(shù)
- 多個參數(shù)之間使用
,
分隔
def sum_2_num(num1, num2):
result = num1 + num2
print("%d + %d = %d" % (num1, num2, result))
sum_2_num(50, 20)
3.2 參數(shù)的作用
- 函數(shù),把 具有獨(dú)立功能的代碼塊 組織為一個小模塊状知,在需要的時候 調(diào)用
-
函數(shù)的參數(shù)秽五,增加函數(shù)的 通用性,針對 相同的數(shù)據(jù)處理邏輯试幽,能夠 適應(yīng)更多的數(shù)據(jù)
- 在函數(shù) 內(nèi)部筝蚕,把參數(shù)當(dāng)做 變量 使用,進(jìn)行需要的數(shù)據(jù)處理
- 函數(shù)調(diào)用時铺坞,按照函數(shù)定義的參數(shù)順序起宽,把 希望在函數(shù)內(nèi)部處理的數(shù)據(jù),通過參數(shù) 傳遞
3.3 形參和實參
- 形參:定義 函數(shù)時济榨,小括號中的參數(shù)坯沪,是用來接收參數(shù)用的,在函數(shù)內(nèi)部 作為變量使用
- 實參:調(diào)用 函數(shù)時擒滑,小括號中的參數(shù)腐晾,是用來把數(shù)據(jù)傳遞到 函數(shù)內(nèi)部 用的
04. 函數(shù)的返回值
- 在程序開發(fā)中叉弦,有時候,會希望 一個函數(shù)執(zhí)行結(jié)束后藻糖,告訴調(diào)用者一個結(jié)果淹冰,以便調(diào)用者針對具體的結(jié)果做后續(xù)的處理
- 返回值 是函數(shù) 完成工作后,最后 給調(diào)用者的 一個結(jié)果
- 在函數(shù)中使用
return
關(guān)鍵字可以返回結(jié)果 - 調(diào)用函數(shù)一方巨柒,可以 使用變量 來 接收 函數(shù)的返回結(jié)果
注意:
return
表示返回樱拴,后續(xù)的代碼都不會被執(zhí)行
def sum_2_num(num1, num2):
"""對兩個數(shù)字的求和"""
return num1 + num2
# 調(diào)用函數(shù),并使用 result 變量接收計算結(jié)果
result = sum_2_num(10, 20)
print("計算結(jié)果是 %d" % result)
05. 函數(shù)的嵌套調(diào)用
- 一個函數(shù)里面 又調(diào)用 了 另外一個函數(shù)洋满,這就是 函數(shù)嵌套調(diào)用
- 如果函數(shù)
test2
中晶乔,調(diào)用了另外一個函數(shù)test1
- 那么執(zhí)行到調(diào)用
test1
函數(shù)時,會先把函數(shù)test1
中的任務(wù)都執(zhí)行完 - 才會回到
test2
中調(diào)用函數(shù)test1
的位置牺勾,繼續(xù)執(zhí)行后續(xù)的代碼
- 那么執(zhí)行到調(diào)用
def test1():
print("*" * 50)
print("test 1")
print("*" * 50)
def test2():
print("-" * 50)
print("test 2")
test1()
print("-" * 50)
test2()
函數(shù)嵌套的演練 —— 打印分隔線
體會一下工作中 需求是多變 的
需求 1
- 定義一個
print_line
函數(shù)能夠打印*
組成的 一條分隔線
def print_line(char):
print("*" * 50)
需求 2
- 定義一個函數(shù)能夠打印 由任意字符組成 的分隔線
def print_line(char):
print(char * 50)
需求 3
- 定義一個函數(shù)能夠打印 任意重復(fù)次數(shù) 的分隔線
def print_line(char, times):
print(char * times)
需求 4
- 定義一個函數(shù)能夠打印 5 行 的分隔線正罢,分隔線要求符合需求 3
提示:工作中針對需求的變化,應(yīng)該冷靜思考驻民,不要輕易修改之前已經(jīng)完成的翻具,能夠正常執(zhí)行的函數(shù)!
def print_line(char, times):
print(char * times)
def print_lines(char, times):
row = 0
while row < 5:
print_line(char, times)
row += 1
06. 使用模塊中的函數(shù)
模塊是 Python 程序架構(gòu)的一個核心概念
- 模塊 就好比是 工具包川无,要想使用這個工具包中的工具呛占,就需要 導(dǎo)入 import 這個模塊
- 每一個以擴(kuò)展名
py
結(jié)尾的Python
源代碼文件都是一個 模塊 - 在模塊中定義的 全局變量 虑乖、 函數(shù) 都是模塊能夠提供給外界直接使用的工具
6.1 第一個模塊體驗
步驟
- 新建
hm_10_分隔線模塊.py
- 復(fù)制
hm_09_打印多條分隔線.py
中的內(nèi)容懦趋,最后一行print
代碼除外 - 增加一個字符串變量
- 復(fù)制
name = "黑馬程序員"
- 新建
hm_10_體驗?zāi)K.py
文件,并且編寫以下代碼:
import hm_10_分隔線模塊
hm_10_分隔線模塊.print_line("-", 80)
print(hm_10_分隔線模塊.name)
體驗小結(jié)
- 可以 在一個 Python 文件 中 定義 變量 或者 函數(shù)
- 然后在 另外一個文件中 使用
import
導(dǎo)入這個模塊 - 導(dǎo)入之后疹味,就可以使用
模塊名.變量
/模塊名.函數(shù)
的方式仅叫,使用這個模塊中定義的變量或者函數(shù)
模塊可以讓 曾經(jīng)編寫過的代碼 方便的被 復(fù)用!
6.2 模塊名也是一個標(biāo)識符
- 標(biāo)示符可以由 字母糙捺、下劃線 和 數(shù)字 組成
- 不能以數(shù)字開頭
- 不能與關(guān)鍵字重名
注意:如果在給 Python 文件起名時诫咱,以數(shù)字開頭 是無法在
PyCharm
中通過導(dǎo)入這個模塊的
6.3 Pyc 文件(了解)
C
是compiled
編譯過 的意思
操作步驟
- 瀏覽程序目錄會發(fā)現(xiàn)一個
__pycache__
的目錄 - 目錄下會有一個
hm_10_分隔線模塊.cpython-35.pyc
文件,cpython-35
表示Python
解釋器的版本 - 這個
pyc
文件是由 Python 解釋器將 模塊的源碼 轉(zhuǎn)換為 字節(jié)碼-
Python
這樣保存 字節(jié)碼 是作為一種啟動 速度的優(yōu)化
-
字節(jié)碼
-
Python
在解釋源程序時是分成兩個步驟的- 首先處理源代碼洪灯,編譯 生成一個二進(jìn)制 字節(jié)碼
- 再對 字節(jié)碼 進(jìn)行處理坎缭,才會生成 CPU 能夠識別的 機(jī)器碼
- 有了模塊的字節(jié)碼文件之后,下一次運(yùn)行程序時签钩,如果在 上次保存字節(jié)碼之后 沒有修改過源代碼掏呼,Python 將會加載 .pyc 文件并跳過編譯這個步驟
- 當(dāng)
Python
重編譯時,它會自動檢查源文件和字節(jié)碼文件的時間戳 - 如果你又修改了源代碼铅檩,下次程序運(yùn)行時憎夷,字節(jié)碼將自動重新創(chuàng)建
提示:有關(guān)模塊以及模塊的其他導(dǎo)入方式,后續(xù)課程還會逐漸展開昧旨!
模塊是 Python 程序架構(gòu)的一個核心概念