首页 > 其他 > 详细

闭包函数、装饰器

时间:2019-07-14 09:18:52      阅读:99      评论:0      收藏:0      [点我收藏+]

闭包函数
1.闭:定义在函数内部的函数
2.包:内部函数引用了外部函数作用域的名字

 闭包函数:只需要传一次参,下面无论在哪用到,直接拿那个名字就可以了

特点:只给内部传参,需要什么传什么,永远不会变

def outter():  #先定义一个outter函数
    x = 111
    def inner():
        print(x)
    return inner
res = outter()  # res就是inner函数内存地址

def func():
    x = 333
    res()
func()

给函数体传值的第一种方式 :传参,直接传递数据

def index1(username):
    print(username)

给函数体传参的第二种方式 闭包(包起来,我给你)

技术分享图片
def outter(x,y):
    # x = 1
    # y = 40
    def my_max():
        if x > y:
            return x
        return y
    return my_max
res1 = outter(1,40)  # res就是my_max函数的内存地址
print(res1())
print(res1())
print(res1())
res2 = outter(90,200)
print(res2())
print(res2())
print(res2())
print(res2())
print(res2())
print(res2())
View Code

需要注意的是

def outter (x,y)
与
def outter():
x = 1
y = 10
这两种本质是一样的,都是在outter里面绑定两个名字,产生两个值

import requests

第一个直接给函数传参

url1 = ‘https://www.baidu.com‘
url2 = ‘...‘
def my_get(url):
    response = requests.get(url)
    if response.status_code == 200:
        print(len(response.text))

my_get(url1)
my_get(url1)
my_get(url1)
my_get(‘https://www.baidu.com‘)
my_get(‘https://www.baidu.com‘)
my_get(‘https://www.baidu.com‘)

第二种给函数传参的方式 闭包

def outter(url):
# url = ‘https://www.jd.com‘
def my_get():
response = requests.get(url)
if response.status_code == 200:
print(len(response.text))
return my_get
my_jd = outter(‘https://www.jd.com‘)
my_jd()
my_jd()
my_baidu = outter(‘https://www.baidu.com‘)
my_baidu()
my_baidu()
my_baidu()
my_baidu()
my_baidu()


装饰器:
器:就是一个工具
装饰:给被装饰对象添加新的功能

为什么要用装饰器
开放封闭原则:
开放:对扩展开放
封闭:对修改封闭

装饰器(可调用对象)必须遵循的两个原则:
1.不改变被装饰对象源代码
2.不改变被装饰对象(可调用对象)调用方式
def index():
pass
index()

如何用
"""
import time  #统计时间
print(time.time())
#1562812014.731474 时间戳 当前时间距离1970-1-1 00:00:00相差的秒数
#1970-1-1 00:00:00是Unix诞生元年


time.sleep(3) # 让cpu谁三秒 让你的程序暂停三秒
print(‘FBI warning!‘)

 

 简单版本装饰器

1.统计index函数执行的时间

import time
def index():
    time.sleep(3)
    print(‘开业了‘)

start = time.time()
index()
end = time.time() #cpu运行代码的时候速度是非常快的,代码与代码之间距离的时间特别的短,
print(‘index run time:%s‘%(end-start))

1.统计index函数执行的时间

import time
def index():
    time.sleep(3)
    print(‘开业了‘)

def outter(func):   #func = index函数的内存地址
    # func = index
    def get_time(func):   #func=index函数
        start = time.time()
        func()   #func=index函数内存地址()  直接调用   运行结束时间
        end = time.time()  #运行结束时间
        print(‘index run time:%s‘%(end-start))
    return get_time
# res = outter(index)   #res变量名   想等于什么就是什么
# res()
index = outter(index)  #函数名只要加括号,优先级最高  outter(最开始的index函数内存地址)
#index指向get_time函数的内存地址
index()

升级版装饰器

 

技术分享图片
import time
def index():
    time.sleep(3)
    print(开业了)

def login(name):   #形参是位置形参
    time.sleep(1)
    print(%s is sb%name)

def outter(func):
    # func = index
    def get_time(*args,**kwargs):   #func = login函数的内存地址
        start = time.time()
        func(*args,**kwargs)   #args = (‘egon‘,)  kwargs={}
        end = time.time()
        print(index run time:%s%(end-start))
    return get_time
# res = outter(index)
# res()
login = outter(login)    #outter(最原始的login函数的内存地址)   login是get_time
login(egon)
index = outter(index)   #最原始的index函数
index()
View Code

函数参数的问题
无参函数和有参函数都可以直接调用???
函数可以接收任意数量的参数

装饰器的模板

def outter(func):
    def inner(*args,**kwargs):
        print(‘执行被装饰函数之前 你可以做的操作‘)
        res = func(*args,**kwargs)
        print(‘执行被装饰函数之后 你可以做的操作‘)
        return res
    return inner

 

装饰器语法糖

@outter  #本质是在最前面

@的工作原理:固定语法会将紧挨着它下面的可调用的名字当做它的参数自动传入,直接执行

例如:

index = outter(index)

(自动outter())

 

技术分享图片
mport time


def outter(func):  # func = 最原始的index函数的内存地址
    def get_time(*args, **kwargs):
        start = time.time()
        res = func(*args, **kwargs)  # 最原始的login函数的内存地址() 直接调用  func(‘egon‘)
        end = time.time()
        print(func run time:%s%(end-start))
        return res
    return get_time
# login = outter(login)  # outter(最原始的login函数的内存地址)
# index = outter(index)
# home = outter(home)

@outter  # index = outter(index)  outter(最原始的index的函数的内存地址)
def index():
    time.sleep(3)
    print(澳门最大线上赌场开业啦 性感tank在线发牌!)
    return index
# res1 = index()




@outter  # login = outter(login)
def login(name):
    time.sleep(1)
    print(%s is sb%name)
    return login
# res = login(‘egon‘)

@outter  # home = outter(home)
def home(*args,**kwargs):
    time.sleep(1)
    return home



# login = outter(login)  # outter(最原始的login函数的内存地址)
# index = outter(index)
# home = outter(home)


index()
login(egon)
home()
View Code

注:语法糖在书写的时候应该与被装饰对象紧紧挨着
两者之间不要有空格

 

闭包函数、装饰器

原文:https://www.cnblogs.com/pangqian/p/11182946.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!