函數

函數:

內置函數(鏈接)
一.函數初始
默認參數的陷阱
默認參數若是可變的數據類型,他始終使用的是一個內存地址。

def func1(x,l1=[]):
    l1.append(x)
    return l1
ret = func1(1)
ret1 = func1(100)

return是函數結束的標志,函數內可以寫多個return,但只執行一次
無return 返回None
只寫return,后面不寫其他內容,也會返回None
return 逗號分隔多個值 返回元組
返回多個值,用多個變量接收
a,b,c,d = ret_demo2()

形參即變量名,實參即變量值
函數即變量 函數的賦值 f = func
命名關鍵字參數:*后定義的參數,必須被傳值(有默認值的除外),且必須按照關鍵字實參的形式傳遞
可以保證,傳入的參數中一定包含某些關鍵字

def foo(位置形參,*args,默認參數,**kwargs):
    函數體
    return 返回值

動態參數
溢出的位置參數值以元祖形式賦給args ,溢出的關鍵字參數以字典的形式賦給kwargs

*args,**kwargs
函數定義時:*聚合  *args:實參里面所有的位置參數。
                   **kwargs:實參里面所有的關鍵字參數。
函數的調用時:* 打散。
形參的順序:位置參數,*args,默認參數,**kwargs。

二.函數進階

存放名字與值的關系’的空間起了一個名字-------命名空間。

全局名稱空間。
臨時名稱空間。
內置名稱空間。
全局作用域: 全局名稱空間,內置名稱空間。
局部作用域: 局部名稱空間。
取值順序:就近原則,從小到大。
加載順序:加載的是名稱空間。
global nonlocal
globals() locals() 以字典形式返回模塊全部全局變量和局部變量

全局作用域:包含內置名稱空間、全局名稱空間
局部作用域:局部名稱空間,只能在局部范圍內生效
  • 函數名的本質。

函數名本質上就是函數的內存地址。

  • 1.可以被引用

  • 2.可以被當作容器類型的元素

  • 3.可以當作函數的參數和返回值

第一類對象(first-class object)指
1.可在運行期創建
2.可用作函數參數或返回值
3.可存入變量的實體。

  • 一句話,函數名能當普通變量用

嵌套函數:
匿名函數:使用一次就釋放

  • lambda x,y:x**y
  • 匿名函數主要是和其它函數搭配使用

高階函數:
變量可以指向函數,函數的參數能接收變量,那么一個函數就可以接收另一個函數作為參數,這種函數就稱之為高階函數。
只需滿足以下任意一個條件,即是高階函數

  • 接受一個或多個函數作為輸入
  • return 返回另外一個函數
def add(x,y,f):
    return f(x) + f(y)

遞歸
在函數內部,可以調用其他函數。如果一個函數在內部調用自身本身,這個函數就是遞歸函數。

查看遞歸次數

n = 1
def func(x):
    print(x)
    x+=1
    func(x)
func(n)
def calc(n):
    v = int(n/2)
    print(v)
    if v > 0:
        calc(v)
    print(n)

calc(10)

遞歸特性:

  • 必須有一個明確的結束條件
  • 每次進入更深一層遞歸時,問題規模相比上次遞歸都應有所減少
  • 遞歸效率不高,遞歸層次過多會導致棧溢出()
    應用:二分查找

閉包原理
閉包函數:內部函數包含對外部作用域而非全劇作用域變量的引用,該內部函數稱為閉包函數,并返回.
閉包的意義:返回的函數對象,不僅僅是一個函數對象,在該函數外還包裹了一層作用域,這使得,該函數無論在何處調用,優先使用自己外層包裹的作用域
應用領域:延遲計算(原來我們是傳參,現在我們是包起來)
閉包作用:
當程序執行時,遇到了函數執行,他會在內存中開辟一個空間,局部名稱空間,
如果這個函數內部形成了閉包,
那么他就不會隨著函數的結束而消失。

name = 'alex'
def wraaper():
    def inner():
        print(name)
    print(inner.__closure__)  # None不是閉包函數
    inner()
    return inner
wraaper()

name = 'hqs'
def wraaper(n):
    n = 'alex'
    def inner():
        print(n)
    print(inner.__closure__)  # cell at 0x000002AD93BF76D8 --> 是閉包函數
    inner()
    return inner
wraaper(name)

可迭代對象:Iterable
: str list dict,tuple,set,range()

對象內部含有iter方法就是可迭代對象.

print('__iter__' in dir(對象))  #返回True.False

from collections import Iterable #判斷是否是可迭代對象
from collections import Iterator #判斷是否是迭代器
print(isinstance('對象',Iterable))  # True/False
print(isinstance('對象',Iterator))  # True/False

可迭代對象滿足可迭代協議。

迭代器:Iterator
對象內部含有__iter__方法且含有__next__方法就是迭代器.
文件本身就是迭代器對象

迭代器的缺點:

  • 取值麻煩,只能一個一個取,只能往后取,
  • 并且是一次性的,無法用len獲取長度

可迭代對象不能取值,迭代器是可以取值的。
可迭代對象 --->(轉化成)迭代器
迭代器=可迭代對象.iter() #等于 迭代器=iter(可迭代對象) #轉化

1,將可迭代對象轉化成迭代器。
2,調用next方法取值。
3,利用異常處理停止報錯。

模式for循環

迭代器 = 可迭代對象.__iter__()
while 1:
    try:
        print(迭代器.__next__())
    except StopIteration:
        break

裝飾器:

開放封閉原則:
軟件上線后,對修改源代碼是封閉的,對功能的擴展功能是開放的。
方案:裝飾器

原則:
    * 1,不修改原代碼
    * 2,不修改調用方式
目的:
    遵循1和2的基礎上拓展新功能

裝飾器:
裝飾為被裝飾對象添加新功能
含義:
裝飾器即在不修改被裝飾對象源代碼與調用方式的前提下,為被裝飾對象添加新功能

    裝飾器 ==》函數
    被裝飾的對象 ==》函數

    time.time() 獲取當前時間(s)

生成器:就是自己python用代碼寫的迭代器,生成器的本質就是迭代器。
generator是可迭代對象 , 可用for循環和next()

用以下兩種方式構建一個生成器:

  • 1,通過生成器函數。
  • 2,生成器表達式。

生成器函數 vs 迭代器:

  • 迭代器是需要可迭代對象進行轉化。可迭代對象非常占內存。
  • 生成器直接創建,不需要轉化,從本質就節省內存。
  • send 與next一樣,也是對生成器取值(執行一個yield)的方法。
  • send 可以給上一個yield 傳值。
  • 第一次取值永遠都是next。
  • 最后一個yield 永遠也得不到send傳的值。
  • yield 將值返回給 生成器對象.next()

迭代器.next() 相當于 next(迭代器)

把函數做成迭代器
* 對比return,可以返回多次值,掛起函數的運行狀態
創建生成器:如下

def func1():  #生成器函數
    print(1)
    count = (yield 6)
    print(count)
    count1 = (yield 7)
    print(count1)
    yield 8

g = func1()  #調用生成器函數創建生成器對象

print(next(g))
print(g.send('alex'))
print(g.send('alex'))
def cloth2(n):
    for i in range(1,n+1):
        yield '衣服%s號' % i
g = cloth2(10000)
for i in range(50):
    print(g.__next__())  #停在50的位置

for i in range(50):      #從51開始
    print(g.__next__())

列表推導式

  • 循環模式 : [變量(加工后的變量) for 變量 in iterable]
  • 篩選模式 : [變量(加工后的變量) for 變量 in iterable if 條件]
    優點:一行解決,方便。
    缺點:容易著迷,不易排錯,不能超過三次循環。
    列表推導式不能解決所有列表的問題,所以不要太刻意用。

生成器表達式:
將列表推導式的 [] 換成() 即可。

三元表達式:ret = 'true' if 1 == 1 else 'false'

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,002評論 6 542
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,400評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,136評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,714評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,452評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,818評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,812評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,997評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,552評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,292評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,510評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,035評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,721評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,121評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,429評論 1 294
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,235評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,480評論 2 379