Python-lesson 3-函數(shù)

1杂靶、函數(shù)知識(shí)體系

  1. 什么是函數(shù)传货?
    在程序中具備某一功能的工具就是函數(shù)
    函數(shù)的使用原則:先定義晃跺、后調(diào)用

  2. 為什么要用函數(shù)?
    (1)代碼冗余
    (2)程序組織結(jié)構(gòu)不清晰也糊、可讀性差
    (3)擴(kuò)展性差

  3. 函數(shù)的分類:
    (1)內(nèi)置函數(shù)
    python自帶的
    (2)自定義函數(shù)
    自己定義的

  4. 自定義函數(shù)和使用
    函數(shù)的定義分為兩個(gè)階段:定義和調(diào)用
    函數(shù)定義: 定義只檢測(cè)語(yǔ)法不執(zhí)行代碼

def 函數(shù)名(參數(shù)1炼蹦,參數(shù)2...):          //必須
"""
文檔注釋
"""
    函數(shù)代碼塊1                  //必須
    函數(shù)代碼塊2
    ...
    return 值

函數(shù)調(diào)用:開(kāi)始執(zhí)行函數(shù)代碼
函數(shù)名()

  1. 定義函數(shù)的三種方式
    (1)無(wú)參函數(shù)
    def func():
    print('......')
    func()

(2)有參函數(shù)
def func(x,y):
if x > y:
return(x)
else:
return(y)

res=func(1,2)

(3)空函數(shù)
def register():
pass

  1. 調(diào)用函數(shù)的三種形式
    (1)語(yǔ)句模式
    def func():
    print('......')
    func()

(2)表達(dá)式形式
def func(x,y):
if x > y:
return(x)
else:
return(y)

res=func(1,2) * 12
print(res)

(3)函數(shù)的調(diào)用可以當(dāng)作另外一個(gè)函數(shù)的參數(shù)傳入
def func(x,y):
if x > y:
return(x)
else:
return(y)

res=func(func(1,2),3)
print(res)

  1. 返回值的特點(diǎn)
    (1)返回值沒(méi)有類型限制,也沒(méi)有個(gè)數(shù)限制
    (2)return是函數(shù)結(jié)束運(yùn)行的標(biāo)志狸剃,函數(shù)內(nèi)可以有多個(gè)return掐隐,但只要執(zhí)行一次return函數(shù)就立即結(jié)束,并且將return后的值當(dāng)作本次調(diào)用的結(jié)果返回钞馁。

  2. 函數(shù)的參數(shù)
    形參即變量名虑省,實(shí)參即變量值,函數(shù)調(diào)用時(shí)僧凰,將值綁定到變量名上探颈,函數(shù)調(diào)用結(jié)束,解除綁定

  3. 函數(shù)參數(shù)詳解
    (1)形參

  • 位置形參:按照從左至右的順序依次定義的形參
    特點(diǎn):必須被傳值

  • 默認(rèn)參數(shù):在定義階段允悦,就已經(jīng)為某個(gè)形參賦值,該形參稱之為默認(rèn)形參
    特點(diǎn):在定義階段就已經(jīng)有值,意味著調(diào)用階段不用為其傳值
    def func(x,y=2):
    print(x,y)

func(1)

注意:位置形參與默認(rèn)形參可以混用隙弛,位置形參必須放在默認(rèn)形參的前面

(2)實(shí)參

  • 位置實(shí)參:在調(diào)用階段架馋,按照從左到右的順序依次傳入的值
    特點(diǎn):這種傳值方式會(huì)與形參一一對(duì)應(yīng)

  • 關(guān)鍵字實(shí)參:在調(diào)用階段,按照key=value的格式傳值
    特點(diǎn):可以完全打亂位置全闷,但仍然能為指定的形參傳值

注意:
1叉寂、可以混用位置實(shí)參與關(guān)鍵字實(shí)參,但是同一個(gè)形參只能被賦值一次
2总珠、位置實(shí)參必須在關(guān)鍵字實(shí)參的前面

(3)形參中*與**的用法

  • 形參中帶*屏鳍,*會(huì)將溢出的位置實(shí)參存成元組的形式然后賦值其后變量名
def func(x,y,*args):
    print(x,y,args)
print(1,2,3,4,5,6)
  • 形參中帶**;**會(huì)將溢出的關(guān)鍵字實(shí)參存成字典的格式然后賦值其后變量名
def func(x,y,**kwargs):
    print(x,y,kwargs)
print(1,y=2,z=3,m=4,n=5)

(4)實(shí)參中* 與**的用法

  • 實(shí)參中帶*局服;先將實(shí)參打散成位置實(shí)參钓瞭,然后再與形參做對(duì)應(yīng)
def func(x,y,z):
    print(x,y,z)

func(*[1,2,3])
func(*'llo')
  • 實(shí)參中帶**;先將實(shí)參打散成關(guān)鍵字實(shí)參淫奔,然后再與形參做對(duì)應(yīng)
def func(x,y,z):
    print(x,y,z)

func(**{'x':1,'z':3,'y':2})    //func(z=3,y=2,x=1)

將一個(gè)函數(shù)的參數(shù)完全轉(zhuǎn)給另一個(gè)函數(shù)

def index(x,y,z)
    print(x,y,z)

def wrapper(*args,**kwargs):           
    index(*args,**kwargs)
#以上兩行意思是將一個(gè)函數(shù)的參數(shù)完全傳給另一個(gè)函數(shù)

wrapper(1,2,3)

2山涡、函數(shù)對(duì)象

函數(shù)對(duì)象:把函數(shù)的內(nèi)存地址當(dāng)作一種變量值去使用,函數(shù)對(duì)象不加()唆迁;如果內(nèi)存地址加()就是在調(diào)用函數(shù)

與變量相同的用法:可以被引用鸭丛、可以當(dāng)作參數(shù)傳遞、返回值可以是函數(shù)唐责、可以被儲(chǔ)存到容器類型(列表鳞溉、字典、元組)

獨(dú)有的用法:加()可以運(yùn)行其內(nèi)部代碼

  1. 可以被引用
def func1()
    print('from func')

func2=func1
func2()
  1. 可以當(dāng)作參數(shù)傳遞
def func1()
    print('from func')

def bar(xxx)
    xxx()

bar(func1)
  1. 返回值可以是函數(shù)
def func1()
    print('from func')

def bar()
    return func1

f=bar()
f()
  1. 可以被儲(chǔ)存到容器類型(列表鼠哥、字典熟菲、元組)
def func1()
    print('from func')

l=[func1,]
l[0]()

3、函數(shù)嵌套

嵌套調(diào)用:在一個(gè)函數(shù)中調(diào)用了另一個(gè)函數(shù)
嵌套定義:在一個(gè)函數(shù)中定義的一個(gè)函數(shù)肴盏,只能在函數(shù)里面使用科盛,外界不能用

def func1()
    print('hello')

def func2()
    print('world')
    func1()

func2()
----------------------------------------
world
hello

4、名稱空間

名稱空間:就是存儲(chǔ)名字與內(nèi)存地址綁定關(guān)系的空間

4.1 名稱空間的分類:

(1)內(nèi)置名稱空間:存儲(chǔ)解釋器自帶的變量名稱與值的對(duì)應(yīng)關(guān)系(print菜皂、len贞绵、max、min)恍飘;python解釋器啟動(dòng)時(shí)創(chuàng)建內(nèi)置名稱空間榨崩,關(guān)閉解釋器銷毀
(2)全局名稱空間:文件級(jí)別的名稱,只要你的名字定義是頂著最左邊(空格也算)寫的就在全局空間章母,除了內(nèi)置的和函數(shù)內(nèi)的母蛛,都是全局名稱空間;執(zhí)行py文件創(chuàng)建全局名稱空間乳怎,關(guān)閉解釋器銷毀
(3)局部名稱空間:只要在函數(shù)里面就是局部的彩郊;調(diào)用函數(shù)時(shí)創(chuàng)建,函數(shù)執(zhí)行完畢銷毀

  • 名稱空間的加載順序
    內(nèi)置的名稱空間--->全局的名稱空間---->局部的

  • 查找順序
    局部的名稱空間---->全局的名稱空間----->內(nèi)置的名稱空間

  • 總結(jié):
    1、名字的查找順序是從當(dāng)前位置往外查找
    2秫逝、名稱空間的嵌套關(guān)系是在函數(shù)定義階段就固定死的恕出,與調(diào)用位置無(wú)關(guān)。

5违帆、作用域(作用范圍)

域:指的是區(qū)域浙巫,范圍的意思
全局的名稱空間和內(nèi)置的名稱空間,在使用上沒(méi)有什么區(qū)別
局部的和全局的內(nèi)置的就區(qū)別了刷后,局部定義的只能在局部使用
函數(shù)的作用域在定義時(shí)就固定了的畴,與調(diào)用的位置沒(méi)有關(guān)系

  • 給三個(gè)空間劃分范圍
    全局的和內(nèi)置的可以劃分為同一個(gè)范圍
    global 表示的全局范圍 ,就是所謂的全局作用域

局部的單獨(dú)劃分為一個(gè)范圍
local 局部作用域

# 查看全局作用域中的內(nèi)容
print(globals())
# 查看全局作用域中的值
print(dir(globals()["_builtins_"]))

#明確使用函數(shù)外的變量
global age(函數(shù)名)

# nonlocal 明確聲明使用上一層的函數(shù)變量尝胆,如果上一層沒(méi)有丧裁,則找上上層的,但是不能找到全局的變量
 nonlocal a(函數(shù)名)

# 查看局部作用域中的內(nèi)容
print(locals())
  • 總結(jié):
    1班巩、如果是不可變類型渣慕,函數(shù)內(nèi)變量值改變不會(huì)改變?nèi)肿兞浚粢淖冃枰暶鞅Щ牛蝗绻强勺冾愋脱疯耄瘮?shù)內(nèi)變量值改變會(huì)改變?nèi)肿兞?br> 2、函數(shù)內(nèi)變量盡量獨(dú)立抑进,不改變?nèi)肿兞俊?/li>

6强经、閉包函數(shù)

閉包函數(shù)與普通函數(shù)的區(qū)別
(1)定義在另一個(gè)函數(shù)中
(2)在內(nèi)部的函數(shù)中使用了外部的變量(不包含全局的變量)

# 為函數(shù)體傳值的方案一:直接以參數(shù)的形式傳入
def f(x):
      print(x)

f(10)

# 為函數(shù)體傳值的方案二:函數(shù)之上傳入,并返回函數(shù)本身寺渗,打包成閉包函數(shù)匿情,并且閉包函數(shù)的調(diào)用賦值給全局變量
def inner():
      x=10
      def f():
            print(x)
      return f       //在返回這個(gè)內(nèi)部的函數(shù)時(shí),不是單純的返回函數(shù)信殊,還把內(nèi)部函數(shù)中訪問(wèn)到的局部名稱一起打包返回炬称,所以叫做閉包函數(shù)
y=inner()
y()
---------------------------------------------
10

# 第二種傳參方式可以演變成:
def inner(x):
      def f():
            print(x)
      return f 

y=inner(11)
y()
----------------------------------------------
11

# _closure_用于訪問(wèn),閉包時(shí)打包的數(shù)據(jù)
print(f._closure_[0].cell_contents)
print(f._closure_[1].cell_contents)

7涡拘、裝飾器

7.1 什么是裝飾器

裝飾器:裝飾器就是一個(gè)用于給其它函數(shù)增加功能的函數(shù)
裝飾器本身可以是任意可調(diào)用對(duì)象
被裝飾對(duì)象本身也可以是任意可調(diào)用對(duì)象

7.2 為什么要用裝飾器

開(kāi)閉原則:對(duì)擴(kuò)展開(kāi)放玲躯,對(duì)修改封閉(可以添加新功能,但是不能修改源代碼和調(diào)用方式)

所以添加新功能鳄乏,但是源代碼不能動(dòng)跷车,調(diào)用方式也不能動(dòng);裝飾器的目的就是在遵循開(kāi)閉原則的基礎(chǔ)上添加新功能

裝飾器 和 閉包函數(shù)的關(guān)系:裝飾器是一種設(shè)計(jì)代碼的套路(在不修改源代碼和調(diào)用方式的情況下增加功能)橱野,要完成裝飾器朽缴,就需要使用閉包函數(shù)

# 裝飾器
import time

def index():
    print("開(kāi)始下載xxx.mp4")
    time.sleep(2)
    print("xxx.mp4 下載完成!")

def outter(func):
    def wrapper():
        start_time = time.time()           //此處可修改水援,添加新功能
        func()
        end_time = time.time()           //此處可修改密强,添加新功能
        print("下載耗時(shí):",(end_time - start_time))
    return wrapper

index=outter(index)    //返回給wrapper內(nèi)存地址茅郎;wrapper內(nèi)存地址中又包括最原始的index內(nèi)存地址
index()

# 裝飾器改進(jìn)
import time

def outter(func):
    @wraps(func)              //將被裝飾對(duì)象的屬性信息傳給新的裝飾器函數(shù)
    def wrapper(*args,**kwargs):     //將參數(shù)完全傳給func()
        start_time = time.time()          
        res=func(*args,**kwargs)      //完全接受wrapper的參數(shù);并且以變量的形式接收f(shuō)unc()的返回值,也就是被裝飾對(duì)象的返回值
        end_time = time.time()         
        print("下載耗時(shí):",(end_time - start_time))
        return res
    return wrapper

@outter                //語(yǔ)法糖或渤;index=outter(index) 只洒,根據(jù)被裝飾函數(shù)的名字,自動(dòng)調(diào)用裝飾器
def index():
    print("開(kāi)始下載xxx.mp4")
    time.sleep(2)
    print("xxx.mp4 下載完成劳坑!")
    return 1234           //被裝飾對(duì)象有返回值

@outter              //語(yǔ)法糖;home=outter(home)
def home(name):      //被裝飾對(duì)象有參數(shù)
    time.sleep(1)
    print('welcome %s to home page' %name)

裝飾器模板

from functools import wraps          //導(dǎo)入functools模塊成畦,裝飾器wraps

def outter(func):
      @wraps(func)              //將被裝飾對(duì)象的所有屬性賦值給wrapper
      def wrapper(*args,**kwargs):
            res=func(*args,**kwargs)
            return res
      return wrapper

@outter
def index():
      time.sleep(1)
      print('welcome to index page')
      return 1234

index()

7.3 多個(gè)裝飾器

多個(gè)裝飾器加載順序:(由被裝飾函數(shù))由下至上
多個(gè)裝飾器執(zhí)行順序:由上至下
加載順序:


image.png

執(zhí)行順序:


image.png

8距芬、三元表達(dá)式

x if x > y else y //條件成立返回左邊,條件不成立返回右邊
res='ok' if True else 'False' //條件成立執(zhí)行左邊循帐,條件不成立執(zhí)行右邊

9框仔、容器表達(dá)式

9.1 列表生成式

l=[i**2 for i in range(10)]    //將for循環(huán)的值按照左邊表達(dá)式直接插入列表

l=[i**2 for i in range(10) if i > 4]   //將for循環(huán)的值判斷條件,符合條件的值按照左邊表達(dá)式直接插入列表

sbs=[name.upper() for name in names if name.endswith('sb')]              //在列表names里拄养,如果有sb結(jié)尾的將其大寫离斩,插入sbs列表

9.2 字典生成式

res=[i:i**2 for i in range(10) if i > 4]
---------------------------------------------------
{5: 25, 6: 36, 7: 49, 8: 64, 9: 81}

9.3 集合生成式

print({i for i in 'hello'})
----------------------------------------------------
{'l', 'o', 'e', 'h'}

10、匿名函數(shù)

匿名函數(shù)就是指定義了一個(gè)函數(shù)的內(nèi)存地址瘪匿,主要用于臨時(shí)使用一次的場(chǎng)景

(lambda x,y:x+y)(1,2)            //x,y為參數(shù)跛梗,沒(méi)有函數(shù)名;冒號(hào)后為代碼塊棋弥,自帶return     
print(res)
-------------------------------------------------
3 

# 匿名函數(shù)通常和其它函數(shù)配合使用
print(max(salaries,key=lambda k:salaries[k]))    //以匿名函數(shù)作為參數(shù)比較大泻顺ァ;key的意思是以什么作為比較的參數(shù)顽染,取最大

# 排序
print(sorted(salaries,key=lambda k:salaries[k],reverse=True))             //以value從大到小排序
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末漾岳,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子粉寞,更是在濱河造成了極大的恐慌尼荆,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,402評(píng)論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件唧垦,死亡現(xiàn)場(chǎng)離奇詭異捅儒,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)业崖,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門野芒,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人双炕,你說(shuō)我怎么就攤上這事狞悲。” “怎么了妇斤?”我有些...
    開(kāi)封第一講書人閱讀 162,483評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵摇锋,是天一觀的道長(zhǎng)丹拯。 經(jīng)常有香客問(wèn)我,道長(zhǎng)荸恕,這世上最難降的妖魔是什么乖酬? 我笑而不...
    開(kāi)封第一講書人閱讀 58,165評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮融求,結(jié)果婚禮上咬像,老公的妹妹穿的比我還像新娘。我一直安慰自己生宛,他們只是感情好县昂,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,176評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著陷舅,像睡著了一般倒彰。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上莱睁,一...
    開(kāi)封第一講書人閱讀 51,146評(píng)論 1 297
  • 那天待讳,我揣著相機(jī)與錄音,去河邊找鬼仰剿。 笑死创淡,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的南吮。 我是一名探鬼主播辩昆,決...
    沈念sama閱讀 40,032評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼旨袒!你這毒婦竟也來(lái)了汁针?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 38,896評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤砚尽,失蹤者是張志新(化名)和其女友劉穎施无,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體必孤,經(jīng)...
    沈念sama閱讀 45,311評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡猾骡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,536評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了敷搪。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片兴想。...
    茶點(diǎn)故事閱讀 39,696評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖赡勘,靈堂內(nèi)的尸體忽然破棺而出嫂便,到底是詐尸還是另有隱情,我是刑警寧澤闸与,帶...
    沈念sama閱讀 35,413評(píng)論 5 343
  • 正文 年R本政府宣布毙替,位于F島的核電站岸售,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏厂画。R本人自食惡果不足惜凸丸,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,008評(píng)論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望袱院。 院中可真熱鬧屎慢,春花似錦、人聲如沸忽洛。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)脐瑰。三九已至,卻和暖如春廷臼,著一層夾襖步出監(jiān)牢的瞬間苍在,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 32,815評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工荠商, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留寂恬,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,698評(píng)論 2 368
  • 正文 我出身青樓莱没,卻偏偏與公主長(zhǎng)得像初肉,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子饰躲,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,592評(píng)論 2 353

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