首页 > 代码库 > <04day>_函数嵌套--闭包函数--装饰器--迭代器--生成器

<04day>_函数嵌套--闭包函数--装饰器--迭代器--生成器

一、函数的嵌套定义

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) #装饰器--函数调用  【@auth2====>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>_函数嵌套--闭包函数--装饰器--迭代器--生成器