码迷,mamicode.com
首页 > 其他好文 > 详细

装饰器、迭代器、生成器

时间:2018-02-23 00:24:12      阅读:203      评论:0      收藏:0      [点我收藏+]

标签:机制   函数对象   int()   bdc   开放封闭原则   闭包函数   doc   color   dex   

一、函数的嵌套和作用域链

1.函数的嵌套调用
技术分享图片
def max(x,y):
     m = x if x > y else y
     return m
 def max1(a,b,c,d):
     res1 = max(a,b)
     res2 = max(res1,c)
     res3 = max(res2,d)
     return res3
 print(max1(23,-7,31,11))
函数的作用嵌套

2.函数的作用域链

小范围作用域可以使用大范围的变量,但是反之不行


技术分享图片
 def f1():
     a = 1
     def f2():
         def f3():
             print(a)
         f3()      #1
     f2()
f1()
函数的作用域链

3.函数名

函数名本质上就是函数的内存地址

(1)可以被引用

技术分享图片
 def func():
     print("in func")
 f =  func
 print(f)    #<function func at 0x0000021011E51E18>
函数名的本质

(2)可以被当作容器类型的元素

技术分享图片函数名
def f1():
    print("f1")
def f2():
    print("f2")
def f3():
    print("f3")

l = [f1,f2,f3]
d = {"f1":f1,"f2":f2,"f3":f3}
l[0]()        #f1()
d["f2"]()     #f2()
被当作容器类型的元素

(3)可以当作函数的参数和返回值

技术分享图片函数名
def f1():
    print("f1")
def f2(argv):
    argv()
    return argv
f = f2(f1)
f()
当作函数的参数和返回值

(4)函数名可以赋值给其他变量
技术分享图片
def func2():
    print(222)
def func3(x):
    print(a)
    return a
a = 3
ret = func3(a)
print(ret)
函数名可以赋值给其他变量

二、第一类对象(first——clss object)

1.可运行期创建
2.可用做函数参数或返回值
3.可存入变量的实体
三、闭包

内层函数,对外层函数(非全局)的变量的引用,叫做闭包
作用:保护内存


1.闭包函数

技术分享图片
def wrapper():
    name = "alex"
    def inner():
        print(name)   #alex
    inner()
wrapper()
闭包函数

2.检查是不是闭包

cell 是闭包,none就不是闭包(面试题)

技术分享图片
def wrapper():
    name = "alex"
    def inner():
        print(name)   #alex
    inner()
    print(inner.__closure__) #cell 是闭包
wrapper()
例子1

在外层函数内部,执行inner()
技术分享图片
def wrapper():
    def inner():
        print(666)
    return inner
wrapper()()

def wrapper():
    def inner():
        print(666)
    inner()
wrapper()
例子2

3.闭包的用处

如果说你内存函数是个闭包,python内部有一个
机制,遇到闭包,他会在内存中开启有一个内存空间,不会关闭。
避免来回开关,不会随着函数的结束而关闭。
直到关闭python解释器,或python内部来回巡回,才会关闭

4.爬虫

from urllib.request import urlopen
print(urlopen("http://www.cnblogs.com/jin-xin/articles/8259929.html").read())
#url 访问某个程序的路径
#uri 访问某个程序路径的 一部分
# 协议名   http  https
# 域名     cnblogs.com
# 项目名   jin-xin
# 模块名   articles
# 页面名   8259929.html
def index(url):
    content = urlopen(url).read()
    def get():
        with open("爬虫","a") as f1:
            f1.write(content.decode("utf-8"))
    return get
index("http://www.cnblogs.com/jin-xin/articles/8259929.html")()

四、装饰器

1.什么是装饰器?
装饰器本质上就是一个python函数,他可以让其他函数在不需要做任何代码变动的前提下,增加额外的功能,
 装饰器的返回值也是一个函数对象。


2.装饰器的应用场景

比如插入日志,性能测试,事务处理,缓存等等场景。

3.简单的装饰器
技术分享图片
import time
def timmer(f):
    def inner():
        start_time = time.time()
        time.sleep(0.1)
        f()
        end_time = time.time()
        print("执行效率%s"%(end_time - start_time))
    return inner
@timmer         #func = timmer(func)
#语法糖,需要放在你像测试函数上面。没有空格。python内部封装语法糖。python内部机制
def func():
    print("完成")
func()
语法糖

4.带参数的装饰器
技术分享图片
import time
def timmer(f):
    def inner(a):
        start_time = time.time()
        time.sleep(0.1)
        f(a)
        end_time = time.time()
        print("执行效率%s"%(end_time - start_time))
    return inner
@timmer         #func = timmer(func)
#语法糖,需要放在你像测试函数上面。没有空格。python内部封装了。python内部机制

def func(a):
    print("%s完成"%a)
func("萌哥")
带参数装饰器例子1
技术分享图片
import time
flag = True
def timmer_out(flag):
    def timmer(func):
        def inner(*args,**kwargs):
            if flag :
                start = time.time()
                time.sleep(0.3)
                ret = func(*args,**kwargs)
                end = time.time()
                print("执行效率%s"%(end - start))
                return ret
            else:
                ret = func(*args,**kwargs)
                return inner

        return inner
    return timmer

@timmer_out(flag)            #1.先判断一下,True或者False 2. @timmer
def f1():
    print(666)
@timmer_out(flag)
def f2():
    print(777)
f1()
f2()
带参数装饰器例子2

 

   5.带返回值装饰器

技术分享图片
import time
def timmer(f):                      #func
    def inner(*args,**kwargs):      #"萌哥"
        start_time = time.time()
        time.sleep(0.1)
        ret = f(*args,**kwargs)     #func("萌哥"),ret==222
        end_time = time.time()
        print("执行效率%s"%(end_time - start_time ))
        return ret
    return inner
@timmer   #func = timmer(func)
def func(a):
    return 222
print(func("萌哥"))  222
带返回值的的装饰器

 

  6.通用装饰器

技术分享图片
def wrapper(func):
    def inner(*args,**kwargs):
        "执行函数前的操作"
        ret = func(*args,**kwargs)
        "执行函数后的操作"
        return ret
    return inner
@wrapper
def func(a):
    print(1)
print(func(a))
通用解释器

 

 7.多个装饰器装饰一个函数

技术分享图片
def wrapper1(func):
    def inner():
        print("wrapper1,before func")
        func()
        print("wrapper1,after func")
    return inner
def wrapper2(func):
    def inner():
        print("wrapper2,before func")
        func()
        print("wrapper2,after func")
@wrapper2
@wrapper1
def f():
    print("in f")
f()
多个装饰器装饰一个函数

 

五、补充知识

1.
函数的有用信息
技术分享图片
def f1():
    ‘‘‘
    本函数的功能:绘图功能,实时接收数据并绘图.
    :return: 绘图需要的数据,返回给前端某标签
    ‘‘‘
    print(f1.__doc__)
    print(f1.__name__)
    print(666)
f1()


# print(f1.__doc__)  #获取函数的说明信息
# print(f1.__name__)  # 获取函数的名字
函数的有用信息

 

  2.开放封闭原则

   1.对扩展是开放的

   2.对修改是封闭的

  3.  *

在执行函数时,加*时打散。
在接受函数时,加*时聚合
技术分享图片
def f1(*args,**kwargs):
    print(args)   # (1, 2, 3, 4)
    # 执行函数时,不加*是聚合。接受函数时加*时聚合
    print(*args)   #1 2 3 4
    # 执行函数时打散,没有任何数据类型 。print()也是一个函数
f1(1,2,3,4)

def f1(*args,**kwargs):
    print(args)   # (1, 2, 3, 4)
    # 执行函数时,不加*是聚合。接受函数时加*时聚合
    print(*args)   #1 2 3 4
    # 执行函数时打散,没有任何数据类型 。print()也是一个函数
f1(*[1,2,3,4])
加*的作用

 

 


装饰器、迭代器、生成器

标签:机制   函数对象   int()   bdc   开放封闭原则   闭包函数   doc   color   dex   

原文地址:https://www.cnblogs.com/lara0520/p/8460509.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!