1. 程式人生 > ><04day>_函數嵌套--閉包函數--裝飾器--叠代器--生成器

<04day>_函數嵌套--閉包函數--裝飾器--叠代器--生成器

key count 內置 嵌套定義 () 3層 logs crm 傳參

一、函數的嵌套定義

1、python函數支持嵌套

def f1():                      #f1函數的定義
    def f2():                  #f2函數的定義
        print(from f2)
        def f3():              #f3函數的定義
            print(from f3)
    f2()
f1()                            

嵌套函數--運行結果說明:

1首先調用f1()結果,f1函數為空。擔保函f2函數,f2函數有內容打印並且有調用,f2函數包含f3函數,但f3函數無調用。

運行結果:

技術分享

列子:多個數據之間的大小比較。

#!/usr/bin/python
# -*- coding:utf-8 -*-
# Author:zhaosj

def max2(x,y):
    return x if x>y else y
def max4(a,b,c,d):
    res1 = max2(a,b)
    res2 = max2(res1,c)
    res3 = max2(res2,d)
    return res3
print(max4(12,88,19,33)) # max4(12,88,19,33)把4個數值傳參數給max4(a,b,c,d)

輸出結果:

技術分享

二、函數、名稱空間作用域

1、名稱空間:全局名稱空間、局部名稱空間;

2、全局名稱空間:文件的執行會產生全局名稱空間,指的是文件級別定義的名字;

文件級別有:

x = 1、if x == 1:、import time.....

3、局部名稱空間:調用函數時會產生局部名稱空間,只在函數調用時臨時綁定,調用結束,綁定即結束。

"""
x = 1000      # 全局名名稱空間
def func():
    x = 1     # 局部名稱空間
    def f1():
        pass
"""

三、閉包函數

閉包函數:

1、內部包含函數;

2、引用外部作用域除全局作用域以外;

列:

#!/usr/bin/python
# -*- coding:utf-8 -*-
# Author:zhaosj

def f1():
    x = 1
    def f2():
        print(x)
    return f2

f = f1()
print(f)
print(f.__closure__[0].cell_contents) 
#closure閉合的意思(只要是閉包函數,那麽次函數就有必合屬性。查看的值是一個元組,取出值.cell_contents)

輸出結果:

技術分享

四、閉包函數的應用--惰性計算
1、利用閉包函數做爬蟲
2、導入一個模塊from urllib.request import urlopen(此模塊比較老,新爬蟲模塊為request)

from  urllib.request import urlopen
zhi = urlopen(http://www.baidu.com).read()
print(zhi.decode(utf-8))# bytes類型想要看懂需要decode,轉換為utf-8

例子:

#!/usr/bin/python
# -*- coding:utf-8 -*-
# Author:zhaosj

from urllib.request import urlopen
def index(url):
    def get():
        return urlopen(url).read()
    return get # 如果沒有return get 把值返回出來那麽只能在內部調用
oldboy = index(http://crm.oldboyedu.com)
print(oldboy().decode(utf-8))

運行結果:

技術分享

五、函數----《裝飾器》

1、裝飾器:修飾別人的工具,修飾添加功能,工具指的就是函數;
2、裝飾器本身可以是任何可調用對象,被裝飾的對象也是任意可調用對象;

無參函數裝飾器:

########################裝飾器##################################
import time
def timmer(func):
    def wrapper(*args,**kwargs):
        start_time=time.time()
        #func() # 原始index函數
        res = func(*args,**kwargs)
        stop_time=time.time()
        print(run time is %s %(stop_time-start_time))
        return res
    return wrapper

####################被裝飾的函數#################################
@timmer  # index=timmer(index)),加上裝飾器,會打印出執行時間的內容
def index():
    time.sleep(3) # 運行三秒在進行打印一下內容
    print(歡迎登陸...)
    return 1
index() #函數調用 wrapper()

裝飾器的調用方式列如:@timmer 【 index=timmer(index))

----------------------------------------------------------------------------------------

裝飾器:--用戶登錄認證:(文件的認證方式)__無參函數

#!/usr/bin/python
# -*- coding:utf-8 -*-
# Author:zhaosj
####################裝飾器########################################
def auth(func):
    def wrapper(*args,**kwargs):
        name = input(輸入用戶名>>:)
        password = input(輸入密碼>>:)
        if name == zhaosj and password == 123:
            print(\033[45m登陸成功[0m)
            res = func(*args,**kwargs)
            return res
        else:
            print(\033[45m登陸失敗\033[0m)
    return wrapper
########################函數功能區#################################
@auth #裝飾器--函數調用
def index():
    print(歡迎登陸首頁)


@auth #裝飾器--函數調用
def home(name):
    print(%s 歡迎來到主頁面 %name)

index()
home(zhaosj)

運行結果:

技術分享

裝飾器:--用戶登錄認證:(認證之後進入系統,做認證記憶__無參函數

#!/usr/bin/python
# -*- coding:utf-8 -*-
# Author:zhaosj
# 定義全局變量,開始時無用戶登陸。默認狀態為沒有登陸狀態
login_user
= {user:None, status:False} ##############################裝飾器######################################### def auth(func): def wrapper(*args,**kwargs):
#判斷有沒有用戶登陸以及當前的登陸狀態,有用戶登錄則不再進行登陸認證
if login_user[user] and login_user[status]: res = func(*args,**kwargs) return res else: # 否則進行用戶登陸認證 name = input(輸入用戶名>>:) password = input(輸入密碼>>:) if name == zhaosj and password == 123: # 判斷輸入的用戶名以及密碼 login_user[user]=zhaosj # 用戶登陸密碼--zhaosj login_user[status]=True # 用戶登陸狀態--True print(\033[45m登陸成功\033[0m) # 登陸成功 res = func(*args,**kwargs) # return res else: print(\033[45m登陸失敗\033[0m) return wrapper ###############################函數功能區######################################## @auth #裝飾器--函數調用 def index(): print(歡迎登陸首頁) @auth #裝飾器--函數調用 def home(name): print(%s 歡迎來到主頁面 %name) index() home(zhaosj)

運行結果:(登陸成功)

技術分享

運行結果:(登陸失敗)

技術分享

裝飾器:--用戶登陸認證__裝飾器,有參函數

有參函數裝飾器只有3層,無參函數裝飾器只有2層

#!/usr/bin/python
# -*- coding:utf-8 -*-
# Author:zhaosj
# 定義全局變量,開始時無用戶登陸。默認狀態為沒有登陸狀態
login_user = {user:None, status:False} #############################裝飾器####################################### def auth(driver = file): def auth2(func): def wrapper(*args,**kwargs): if driver == file: print(================file的認證) ###############################認證功能######################################
#判斷有沒有用戶登陸以及當前的登陸狀態,有用戶登錄則不再進行登陸認證
                if login_user[user] and login_user[status]: 
                    res = func(*args,**kwargs)
                    return  res
                else: # 否則進行用戶登陸認證
                    name = input(輸入用戶名>>:)
                    password = input(輸入密碼>>:)

                    if name == zhaosj and password == 123: # 判斷輸入的用戶名以及密碼
                        login_user[user]=zhaosj # 用戶登陸密碼--zhaosj
                        login_user[status]=True   # 用戶登陸狀態--True
                        print(\033[45m登陸成功\033[0m) # 登陸成功
                        res = func(*args,**kwargs) #
                        return res
                    else:
                        print(\033[45m登陸失敗\033[0m)
##############################################################################
            elif driver == ldap:
                print(===================ldap的認證)
            elif driver == mysql:
                print(===================mysql的認證)
                #return func(*args,**kwargs)
            else:
                print(===================未知認證方式)
        return wrapper
    return auth2
#############################函數功能區###########################################
@auth(file) #裝飾器--函數調用  [email protected]====>index=auth2(index)====>index=wrapper】
def index():
    print(歡迎登陸首頁)

@auth(driver=mysql) #裝飾器--函數調用
def home(name):
    print(%s 歡迎來到主頁面 %name)

index()  #wrapper
home(zhaosj)#wrapper(zhaosj)

運行結果:

技術分享

技術分享

六、叠代器

叠代器的概念:
重復的過程稱為叠代,每次重復即一次叠代,並且每次叠代的結果是下一次叠代的初始值;

1、叠代一個--<列表>

zhaosj_list = [0,1,2,3]
count = 0
while count < len(zhaosj_list):
    print(=======>,zhaosj_list[count])
    count += 1

運行結果:

技術分享

2、叠代一個--<元組>

zhaosj_tulop = (0,1,2,3)
count = 0
while count < len(zhaosj_tulop):
    print(========>,zhaosj_tulop[count])
    count += 1

運行結果:

技術分享

3、叠代--<字符串>

zhaosj_str = zhaoshujing
count = 0
while count < len(zhaosj_str):
    print("============",zhaosj_str[count])
    count += 1

運行結果:

技術分享

為什麽需要叠代器?
對於沒有索引的數據類型(像:字典-dic、集合-set。就沒有索引)必須提供一種不依賴與索引的叠代方式

可叠代對象;
可叠代的對象:內置__iter__()方法的都是可叠代對象;

[1,2].__iter__()          #列表
zhaosj.__iter__()       #字符串
(1,2).__iter__()          #元組
{a:1,b:2}.__iter__()  #字典
{1,2,3}.__iter__()        #集合

叠代器:執行__iter__方法,得到的結果就是叠代器
叠代器:可執行__next__()方法的都是叠代器。

i = [1,2,3].__iter__()
print(i)
print(i.__next__()) # 每執行一次,就會取一次值(不能一次全取)
print(i.__next__())

運行結果:

技術分享

字典生成--叠代器--取出 字典中的值

dic = {a:1,b:2,c:3}
i = dic.__iter__()         #字典生成叠代器

print(i.__next__())       #next一次取出一個key
print(i.__next__())
print(i.__next__())

技術分享

字典生成--叠代器--後取出字典中的值

dic = {a:1,b:2,c:3}
i = dic.__iter__() #字典生成叠代器
# 字典生成叠代器後取出字典中的值
while True:
    try:
        key = i.__next__()
        print(dic[key])
    except StopIteration: # 異常處理,捕捉異常。遇到異常執行break
        break

運行結果:

技術分享

查看一個字符串的長度

s = hello
print(len(s)) # len(s) ===s.__len__()

運行結果:

技術分享

七、生成器

生成器---生成器函數(只要函數體包含yield關鍵字,該函數就是生成器);
yield 與 return相似,但是return只執行一次就結束,yield只會暫時掛起;
yield 會把函數變成叠代器;

#!/usr/bin/python
# -*- coding:utf-8 -*-
# Author:zhaosj

def foo():
    print(first)
    yield 1 # 遇到yield掛起,返回參數。
    print(second)
    yield 2
    print(third)
    yield 3
    print(fourth)
    yield 4
    print(ffth)

g = foo()  #next(g) 觸發叠代器g的執行,進而觸發函數的執行
print(next(g))
print(next(g))

運行結果:

技術分享

<04day>_函數嵌套--閉包函數--裝飾器--叠代器--生成器