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

函数进阶

时间:2018-05-22 17:19:47      阅读:187      评论:0      收藏:0      [点我收藏+]

标签:去掉   shu   inf   out   eva   bubuko   rgs   col   领域   

一、闭包

闭包:1,闭:内部的函数

   2,包:包含了对外部函数作用域中变量的应用

外部可以执行内部函数,并且还可以用内部函数作用域中的值

闭包的意义:返回的函数对象,不仅仅是一个函数对象,在该函数外还包裹了一层作用域,这使得,该函数无论在何处调用,优先使用自己外层包裹的作用域

def func():
    n = 1
    def func2():
        ‘‘‘闭包‘‘‘
        print("from func2:",n)
    return func2
f = func()
print(f)
f()

判断闭包函数的方法:__closure__

技术分享图片
#判断闭包函数的方法,有cell就是闭包函数,None则不是
def func():
    n = 1
    def func2():
        ‘‘‘闭包‘‘‘
        print("from func2:",n)
    print(func2.__closure__)
    return func2
f = func()
f()

#非闭包函数
n = 1
def func():
    def func2():
        print("from func2:",n)
    print(func2.__closure__)
    return func2
f = func()
f()
判断闭包函数

查看闭包的元素

技术分享图片
def func():
    n = 1
    def func2():
        print("from func2:",n)
    print(func2.__closure__)
    return func2
f = func()
f()
print(f.__closure__[0].cell_contents)  #查看闭包元素
__closure__[0].cell_contents

应用领域:延迟计算

技术分享图片
from urllib.request import urlopen
# res = urlopen(‘http://www.baidu.com‘).read()
# print(res.decode(‘utf-8‘))
def index(url):
    def get():
        return urlopen(url).read()
    return get
baidu = index(http://www.baidu.com)
print(baidu().decode(utf-8))
print(baidu.__closure__[0].cell_contents) #查看闭包的元素
先用传参,后用闭包
技术分享图片
def func():
    money = 1000
    def func1():
        name = chris
        def func2():
            print(name,money)
        return func2
    return func1
f = func()  #拿到func的内存地址
a = f()   #拿到func2的内存地址
a()
闭包嵌套

 二、装饰器

装饰器的功能:在不修改原函数(代码)及其调用方式的情况下对原函数功能进行扩展

装饰器的本质:就是一个闭包函数

简单装饰器:实现函数执行时间

 

import time
def timer(func):
    def inner():
        start_time = time.time()
        func() #timer函数的参数
        stop_time = time.time()
        print(run time is ,stop_time-start_time)
    return inner
def func():
    time.sleep(2)
    print("from func")
func = timer(func)  #拿到的是inner的内存地址
func()

 

技术分享图片

第7/8可使用语法糖改进(装饰器)

import time

def timer(func):
    def inner():
        start_time = time.time()
        func()
        stop_time = time.time()
        print(run time is , stop_time - start_time)

    return inner

@timer  #把整下方的函数当做参数传递,相当于implement=timer(implement)
def implement():   
    time.sleep(2)
    print("from func")
implement()

技术分享图片

技术分享图片
import time

def timer(func):
    def inner(*args,**kwargs):
        start_time = time.time()
        res = func(*args,**kwargs)
        stop_time = time.time()
        print(run time is , stop_time - start_time)
        return res
    return inner

@timer  #把整下方的函数当做参数传递,相当于implement=timer(implement)
def implement(a):
    time.sleep(2)
    print("from func :%s"%a)
@timer
def implement2(a,b):
    time.sleep(0.1)
    print("from func:",a,b)
implement(abcd)
implement2(3,4)
带参数的装饰器
技术分享图片
import time

def timer(func):
    def inner(*args,**kwargs):
        start_time = time.time()
        res = func(*args,**kwargs)
        stop_time = time.time()
        print(run time is , stop_time - start_time)
        return res
    return inner

@timer  #把整下方的函数当做参数传递,相当于implement=timer(implement)
def implement(a):
    time.sleep(0.2)
    print("from func :%s"%a)
    return implement over
# implement(‘abc‘)
print(implement(abc))
带返回值的装饰器

三、开放封闭原则

1,对外部扩展是开放的

2,对内部修改是封闭的

四、装饰器的固定结构

技术分享图片
import time
def wrapper(func):  # 装饰器
    def inner(*args, **kwargs):
        ‘‘‘函数执行之前的内容扩展‘‘‘
        ret = func(*args, **kwargs)
         ‘‘‘函数执行之前的内容扩展‘‘‘
        return ret
    return inner

@wrapper  # =====>implement=timmer(implement)
def implement():
    time.sleep(1)
    print(abcd)
implement()
固定格式

五、带参数的装饰器

带参数的装饰器顾名思义就是给装饰器传参

用处:当加了很多装饰器的时候,忽然不想加装饰器了想把装饰器给去掉,但代码比较多,删起来比较麻烦,那么我们可以利用带参数的装饰器去装饰它,这就像一个开关,要的时候调用,不用的时候去掉。给装饰器里面传个参数,那么语法糖也要加括号【eg:@timer()】。在语法糖的括号内传参。我们可以用三层嵌套,弄一个标识位去标识。如下代码:

技术分享图片
# 带参数的装饰器:(相当于开关)为了给装饰器传参
# F=True#为True时就把装饰器给加上了
F=False#为False时就把装饰器给去掉了
def outer(flag):
    def wrapper(func):
        def inner(*args,**kwargs):
            if flag:
                print(before)
                ret=func(*args,**kwargs)
                print(after)
            else:
                ret = func(*args, **kwargs)
            return ret
        return inner
    return wrapper

@outer(F)#@wrapper
def hahaha():
    print(hahaha)

@outer(F)
def shuangwaiwai():
    print(shuangwaiwai)

hahaha()
shuangwaiwai()
给装饰器加参数

六、多个装饰器装饰一个函数

技术分享图片
import time
user_status = False
def auth(func):
    ‘‘‘auth.txt内容为{"name":"chris","password":"123"}‘‘‘
    file = auth.txt
    with open(file,r+,encoding=utf-8) as f:
        data = eval(f.read())
        global user_status
        if user_status == False:
            user_name = input(username:).strip()
            pass_word = input(password:).strip()
            if data[name] == user_name and data[password] == pass_word:
                print("welcome %s".center(20,-)%user_name)
                user_status = True
            else:
                print("wrong username or password")
        # else:
        #     print(‘无需验证‘)
    return func

def timer(func):
    def inner():
        start_time = time.time()
        func()
        stop_time = time.time()
        print(run time is ,stop_time-start_time)
    return inner

@auth
@timer
def func():
    time.sleep(2)
    print("from func")


func()
‘‘‘
@auth和@timer的顺序是先执行 auth里面的认证信息,再执行timer函数中的时间
‘’‘
多个装饰器装饰一个函数
技术分享图片
def qqqxing(fun):
    def inner(*args,**kwargs):
        print(in qqxing: before)
        ret = fun(*args,**kwargs)
        print(in qqxing: after)
        return ret
    return inner

def pipixia(fun):
    def inner(*args,**kwargs):
        print(in qqxing: before)
        ret = fun(*args,**kwargs)
        print(in qqxing: after)
        return ret
    return inner
@qqqxing
@pipixia
def dapangxie():
    print(饿了吗)
dapangxie()

‘‘‘
@qqqxing和@pipixia的执行顺序:先执行qqqxing里面的 print(‘in qqxing: before‘),然后跳到了pipixia里面的
        print(‘in qqxing: before‘)
        ret = fun(*args,**kwargs)
        print(‘in qqxing: after‘),
        完了又回到了qqqxing里面的print(‘in qqxing: after‘)。所以就如下面的运行结果截图一样
‘‘‘
多个装饰器修饰一个函数

技术分享图片

七、统计多少个函数被装饰了的应用

技术分享图片
F=False
l = []
def outer(flag):
    def wrapper(func):
        l.append(func)
        def inner(*args,**kwargs):
            if flag:
                print(before)
                ret = func(*args,**kwargs)
                print(after)
            else:
                ret = func(*args, **kwargs)
            return ret
        return inner
    return wrapper

@outer(F)#@wrapper
def hahaha():
    print(hahaha)

@outer(F)
def shuangwaiwai():
    print(shuangwaiwai)

hahaha()
shuangwaiwai()
print(l)
View Code

 

函数进阶

标签:去掉   shu   inf   out   eva   bubuko   rgs   col   领域   

原文地址:https://www.cnblogs.com/chris3201/p/9008424.html

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