2019-11-10 # 函數(shù)基礎(chǔ)

目標(biāo)

  • 函數(shù)的快速體驗
  • 函數(shù)的基本使用
  • 函數(shù)的參數(shù)
  • 函數(shù)的返回值
  • 函數(shù)的嵌套調(diào)用
  • 在模塊中定義函數(shù)

01. 函數(shù)的快速體驗

1.1 快速體驗

  • 所謂函數(shù),就是把 具有獨(dú)立功能的代碼塊 組織為一個小模塊懒鉴,在需要的時候 調(diào)用
  • 函數(shù)的使用包含兩個步驟:
    1. 定義函數(shù) —— 封裝 獨(dú)立的功能
    2. 調(diào)用函數(shù) —— 享受 封裝 的成果
  • 函數(shù)的作用屈嗤,在開發(fā)程序時彭谁,使用函數(shù)可以提高編寫的效率以及代碼的 重用

演練步驟

  1. 新建 04_函數(shù) 項目
  2. 復(fù)制之前完成的 乘法表 文件
  3. 修改文件,增加函數(shù)定義 multiple_table():
  4. 新建另外一個文件隶校,使用 import 導(dǎo)入并且調(diào)用函數(shù)

02. 函數(shù)基本使用

2.1 函數(shù)的定義

定義函數(shù)的格式如下:

def 函數(shù)名():

    函數(shù)封裝的代碼
    ……
  1. def 是英文 define 的縮寫
  2. 函數(shù)名稱 應(yīng)該能夠表達(dá) 函數(shù)封裝代碼 的功能唆缴,方便后續(xù)的調(diào)用
  3. 函數(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ù)演練

需求

    1. 編寫一個打招呼 say_hello 的函數(shù)狼讨,封裝三行打招呼的代碼
    1. 在函數(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ù)

演練需求

  1. 開發(fā)一個 sum_2_num 的函數(shù)
  2. 函數(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ù)
    1. 在函數(shù) 內(nèi)部筝蚕,把參數(shù)當(dāng)做 變量 使用,進(jìn)行需要的數(shù)據(jù)處理
    2. 函數(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ù)的代碼
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 代碼除外
    • 增加一個字符串變量
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 文件(了解)

Ccompiled 編譯過 的意思

操作步驟

  1. 瀏覽程序目錄會發(fā)現(xiàn)一個 __pycache__ 的目錄
  2. 目錄下會有一個 hm_10_分隔線模塊.cpython-35.pyc 文件,cpython-35 表示 Python 解釋器的版本
  3. 這個 pyc 文件是由 Python 解釋器將 模塊的源碼 轉(zhuǎn)換為 字節(jié)碼
    • Python 這樣保存 字節(jié)碼 是作為一種啟動 速度的優(yōu)化

字節(jié)碼

  • Python 在解釋源程序時是分成兩個步驟的
    1. 首先處理源代碼洪灯,編譯 生成一個二進(jìn)制 字節(jié)碼
    2. 再對 字節(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)的一個核心概念

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末拾给,一起剝皮案震驚了整個濱河市祥得,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌蒋得,老刑警劉巖级及,帶你破解...
    沈念sama閱讀 206,013評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異额衙,居然都是意外死亡创千,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,205評論 2 382
  • 文/潘曉璐 我一進(jìn)店門入偷,熙熙樓的掌柜王于貴愁眉苦臉地迎上來追驴,“玉大人,你說我怎么就攤上這事疏之〉钛” “怎么了?”我有些...
    開封第一講書人閱讀 152,370評論 0 342
  • 文/不壞的土叔 我叫張陵锋爪,是天一觀的道長丙曙。 經(jīng)常有香客問我,道長其骄,這世上最難降的妖魔是什么亏镰? 我笑而不...
    開封第一講書人閱讀 55,168評論 1 278
  • 正文 為了忘掉前任,我火速辦了婚禮拯爽,結(jié)果婚禮上索抓,老公的妹妹穿的比我還像新娘。我一直安慰自己毯炮,他們只是感情好逼肯,可當(dāng)我...
    茶點故事閱讀 64,153評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著桃煎,像睡著了一般篮幢。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上为迈,一...
    開封第一講書人閱讀 48,954評論 1 283
  • 那天三椿,我揣著相機(jī)與錄音,去河邊找鬼葫辐。 笑死搜锰,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的另患。 我是一名探鬼主播纽乱,決...
    沈念sama閱讀 38,271評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼昆箕!你這毒婦竟也來了鸦列?” 一聲冷哼從身側(cè)響起租冠,我...
    開封第一講書人閱讀 36,916評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎薯嗤,沒想到半個月后顽爹,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,382評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡骆姐,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,877評論 2 323
  • 正文 我和宋清朗相戀三年镜粤,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片玻褪。...
    茶點故事閱讀 37,989評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡肉渴,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出带射,到底是詐尸還是另有隱情同规,我是刑警寧澤,帶...
    沈念sama閱讀 33,624評論 4 322
  • 正文 年R本政府宣布窟社,位于F島的核電站券勺,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏灿里。R本人自食惡果不足惜关炼,卻給世界環(huán)境...
    茶點故事閱讀 39,209評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望匣吊。 院中可真熱鬧儒拂,春花似錦、人聲如沸缀去。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,199評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽缕碎。三九已至,卻和暖如春池户,著一層夾襖步出監(jiān)牢的瞬間咏雌,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,418評論 1 260
  • 我被黑心中介騙來泰國打工校焦, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留赊抖,地道東北人。 一個月前我還...
    沈念sama閱讀 45,401評論 2 352
  • 正文 我出身青樓寨典,卻偏偏與公主長得像氛雪,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子耸成,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,700評論 2 345

推薦閱讀更多精彩內(nèi)容