1、闭包: 保护数据安全、保护数据干净性。

2、闭包的定义:在嵌套函数内、使用非全局变量(且不使用本层变量)

        将嵌套函数返回

闭包的目的:要接受被装饰的函数和被装饰函数需要的参数
3、闭包举例子:

def func():
a = 10
def foo():
print(a)
return foo
f = func()
f()
结果:10
4、验证闭包函数:__closure__
def func():
a = 10          #自由变量
def foo():
print(a)      #打印a有一个绑定关系
return foo
f = func()
print(f.__closure__)
结果:(<cell at 0x0000000001E285E8: int object at 0x00000000525A8190>,)
5、函数体执行完以后将函数体开辟的空间都释放掉了
6、模拟买车求平均价版一:
lst = []
def buy_car(price):
lst.append(price)
arg = sum(lst) / len(lst)
print(arg)
buy_car(120000) #周一
buy_car(240000) #周二
buy_car(10000000) #周三
buy_car(5500000) #周四
buy_car(120000) #周五
buy_car(50000000) #周六
buy_car(5000000) #周日
结果:   120000.0

      180000.0
      3453333.3333333335
      3965000.0
      3196000.0
      10996666.666666666
      10140000.0

7、版二:查看闭包函数里面的自由变量__code__.co_freevars:

def buy_car():
lst = []
def func(price):
lst.append(price)
arg = sum(lst) / len(lst)
print(arg)
return func
f = buy_car()
print(f.__code__.co_freevars)
f(1)
f(2)
f(3)
f(4)
f(5)
结果:('lst',)

    1.0
    1.5
    2.0
    2.5
    3.0

8、查看闭包函数里面的局部变量__code__.co_varnames:

def buy_car():
lst = []
def func(price):
lst.append(price)
arg = sum(lst) / len(lst)
print(arg)
return func
f = buy_car()
print(f.__code__.co_freevars)
print(f.__code__.co_varnames)
f(1)
f(2)
f(3)
f(4)
f(5)
结果:('lst',)

    ('price', 'arg')
    1.0
    1.5
    2.0
    2.5
    3.0

9、没有将嵌套的函数返回也是一个闭包、但是这个闭包不是一个可使用的闭包:

def func():
a = 10
def foo():
print(a)
print(foo.__closure__)
func()
# 结果:(<cell at 0x00000000021785E8: int object at 0x00000000592F8190>,)
10、闭包就是需要打开两次而已:
11、以下也是一个闭包:
def wrapper(a,b):
   #a = 1    #隐形传参/隐形定义变量和后续的隐形接收传参
   #b = 2
def inner():
print(a)
print(b)
return inner
a = 2
b = 3
ret = wrapper(a,b)
print(ret.__closure__)
# 结果:(<cell at 0x0000000001E185E8: int object at 0x00000000592F8090>, <cell at 0x0000000001E18618: int object at 0x00000000592F80B0>)
12、闭包的应用场景:
          
1、装饰器
          2、防止数据被误改动
装饰器的本质就是闭包
13、生成器的本质就是迭代器:          
14、开放封闭原则:
         
 1、对扩展开放--支持增加新功能
          2、对修改源代码是封闭,对调用方式是封闭的
15、装饰(在原有的基础上额外添加功能)器--工具:
16、装饰器运行图:

17、语法糖:
语法糖必须放在被装饰的函数正上方
      语法糖的本质就是index = run_time(index)
      函数名可以当做另一个函数参数
     
 函数名可以当做另一个函数的返回值
      函数名可以当做值赋值给变量
import time
def run_time(f):
def inner():
start_time = time.time() #被装饰函数之前
f()
print(time.time() - start_time) #被装饰函数之后
return inner
@run_time
def index():
print("is index 海绵")
index()
18、有参装饰器:
import time
def run_time(f): #f接收的是被装饰的函数名
def inner(*args,**kwargs): #被装饰的函数需要的参数
print("外挂开启")
f(*args,**kwargs)
print("外挂关闭")
return inner
@run_time
def index(user,pwd,hero):
print("打开游戏")
print(f"登录{user}和{pwd}")
print(f"选择英雄:{hero}")
print("游戏中")
print("游戏结束")
index("meet","123456","草丛伦")
19、有参装饰器有返回值时:
def run_time(f):                    #f接收的是被装饰的函数名
def inner(*args,**kwargs): #被装饰的函数需要的参数
print("外挂开启")
ret = f(*args,**kwargs)
print("外挂关闭")
return ret
return inner
@run_time
def index(user,pwd,hero):
print("打开游戏")
print(f"登录{user}和{pwd}")
print(f"选择英雄:{hero}")
print("游戏中")
return "游戏结束"
print(index("meet","123456","草丛伦"))
20、标准版装饰器:
def wrapper(func):
def inner(*args,**kwargs):
"""执行被装饰函数前的操作"""
func(*args,**kwargs)
"""执行被装饰函数后的操作"""
return inner
@wrapper
def index():
print("is index")
index()
21、将来有可能会问:
语法糖要接受的变量就是语法糖下面的函数名、参数就是语法糖下面的函数名、调用的方式就是看调用的哪个语法糖
def func(args):
print("新加了一个功能")
return args
@func #index = func(index)
def index():
print(2)
index()
结果:  新加了一个功能

     2

22、作业题:

# 1、用内置函数或者和匿名函数结合做出
# 2、用map来处理下述l,然后用list得到一个新的列表,列表中每个人的名字都是sb结尾
l=[{'name':'alex'},{'name':'y'}]
print(list(map(lambda x:x["name"] + "sb",l)))
# 3、用filter来处理,得到股票价格大于20的股票名字
# shares={
# 'IBM':36.6,
# 'Lenovo':23.2,
# 'oldboy':21.2,
# 'ocean':10.2,
# }
# print(list(filter(lambda i:shares[i] > 20,shares)))
# 4、有下面字典,得到购买每只股票的总价格,并放在一个迭代器中。
# 结果:list一下[9110.0, 27161.0,......]
# portfolio = [
# {'name': 'IBM', 'shares': 100, 'price': 91.1},
# {'name': 'AAPL', 'shares': 50, 'price': 543.22},
# {'name': 'FB', 'shares': 200, 'price': 21.09},
# {'name': 'HPQ', 'shares': 35, 'price': 31.75},
# {'name': 'YHOO', 'shares': 45, 'price': 16.35},
# {'name': 'ACME', 'shares': 75, 'price': 115.65}]
print(list(map(lambda i:i["shares"] * i["price"],portfolio)))
# 5、还是上面的字典,用filter过滤出单价大于100的股票。
print(list(filter(lambda x:x["price"] > 100,portfolio)))
# 6、有下列三种数据类型,
# l1 = [1,2,3,4,5,6]
# l2 = ['oldboy','alex','wusir','太白','日天']
# tu = ('**','***','****','*******')
# 写代码,最终得到的是(每个元祖第一个元素>2,第三个*至少是4个。)
# [(3, 'wusir', '****'), (4, '太白', '*******')]
# 7、有如下数据类型(实战题):
# l1 = [{'sales_volumn': 0},
# {'sales_volumn': 108},
# {'sales_volumn': 337},
# {'sales_volumn': 475},
# {'sales_volumn': 396},
# {'sales_volumn': 172},
# {'sales_volumn': 9},
# {'sales_volumn': 58},
# {'sales_volumn': 272},
# {'sales_volumn': 456},
# {'sales_volumn': 440},
# {'sales_volumn': 239}]
# 将l1按照列表中的每个字典的values大小进行排序,形成一个新的列表。
print(sorted(l1,key=lambda x:x["sales_volumn"]))
# 8、有如下数据结构,通过过滤掉年龄大于16岁的字典
# lst = [{'id':1,'name':'alex','age':18},
# {'id':1,'name':'wusir','age':17},
# {'id':1,'name':'taibai','age':16},]
print(list(filter(lambda x:x["age"] > 16,lst)))
# 9、有如下列表,按照元素的长度进行升序
# lst = ['天龙八部','西游记','红楼梦','三国演义']
print(sorted(lst,key = len))
# 10、有如下数据,按照元素的年龄进行升序
# lst = [{'id':1,'name':'alex','age':18},
# {'id':2,'name':'wusir','age':17},
# {'id':3,'name':'taibai','age':16},]
print(sorted(lst,key=lambda x:x["age"]))
# 11、看代码叙说,两种方式的区别
# lst = [1,2,3,5,9,12,4]
# lst.reverse() #原地修改
# print(lst)
# print(list(reversed(lst))) #新开辟了一个列表
# 12、求结果(面试题)
# v = [lambda :x for x in range(10)] #首先这个一整体是列表推导式
# print(v)
#结果是10个函数的内存地址:[<function <listcomp>.<lambda> at 0x000000000221AB70>, <function <listcomp>.<lambda> at 0x000000000221AA60>, <function <listcomp>.<lambda> at 0x000000000221AC80>, <function <listcomp>.<lambda> at 0x000000000221ABF8>, <function <listcomp>.<lambda> at 0x000000000221AD08>, <function <listcomp>.<lambda> at 0x000000000221AD90>, <function <listcomp>.<lambda> at 0x000000000221AE18>, <function <listcomp>.<lambda> at 0x000000000221AEA0>, <function <listcomp>.<lambda> at 0x000000000221AF28>, <function <listcomp>.<lambda> at 0x0000000002223048>]
# print(v[0])
#从10个函数内存地址里面拿到第一个函数的内存地址:[<function <listcomp>.<lambda> at 0x000000000221AB70>
# print(v[0]()) #第一个函数的内存地址加括号运行不用加参数、因为lambda函数里面没有形参、x是for循环的最后一个数9
# 13、求结果(面试题)
# v = (lambda :x for x in range(10))
# print(v) #生成器的内存地址
# print(v[0]) #报错生成器对象不可订阅
# print(v[0]()) #报错生成器对象不可订阅
# print(next(v)) #函数的内存地址
# print(next(v)()) #运行结果是1
# 14、map(str,[1,2,3,4,5,6,7,8,9])输出是什么? (面试题)
#结果:<map object at 0x00000000021C77B8> #
# 15、有一个数组[34,1,2,5,6,6,5,4,3,3]请写一个函数,找出该数组中没有重复的数的总和(上面数据没有重复的总和为1+2+34=40)(面试题)
#for循环写法:
lst = [34,1,2,5,6,6,5,4,3,3]
num = 0
for i in lst:
if lst.count(i) == 1:
num += i
print(num)
#sum求和:
print(sum([x for x in lst if lst.count(x) == 1]))
#filter过滤:
print(sum(list(filter(lambda x:lst.count(x) == 1,lst))))
# 16、求结果:(面试题)
# def num():
# return [lambda x:x**i for i in range(4)]
# print([m(2)for m in num()])
# 结果:[8, 8, 8, 8]
# 17、看代码写结果:
# def wrapper(f):
# def inner(*args, **kwargs):
# print(111)
# ret = f(*args, **kwargs)
# print(222)
# return ret
# return inner
# def func():
# print(333)
# print(444)
# func()
# print(555)
# 18、编写装饰器, 在每次执行被装饰函数之前打印一句’每次执行被装饰函数之前都得先经过这里’。
def wrapper(f):
def innder(*args,**kwargs):
print("每次执行被装饰函数之前都得先经过这里")
ret = f(*args,**kwargs)
print("嘿嘿嘿")
return innder
@wrapper #func = wrapper(func)
def func():
print("i am name 张达")
func()
# 19、为函数写一个装饰器,把函数的返回值 + 100然后再返回。
def wrapper(func):
def inner(*args,**kwargs):
return func(*args,**kwargs) + 100
return inner
@wrapper
def func():
return 7
result = func()
print(result)
# 23、请实现一个装饰器,每次调用函数时,将被装饰的函数名以及调用被装饰函数的时间节点写入文件中。可用代码如下:
def wrapper(func):
def inner(*args,**kwargs):
import time
struct_time = time.localtime()
time_str = time.strftime("%Y-%m-%d %H:%M:%S",struct_time) #获取当前时间节点
with open("info","a",encoding="utf-8") as f:
f.write(f"时间:{time_str} 函数名:{func.__name__}\n")
func(*args,**kwargs)
print("写入成功!")
return inner
@wrapper
def func():
print(func.__name__) #现在看到的func已经是inner了
print("我被执行了")
func()
# inner
# 我被执行了
# 写入成功!

python27期day13:闭包、装饰器初始、标准版装饰器、作业题的更多相关文章

  1. python27期day09:函数的初始、函数的定义、函数的调用、函数的返回值、函数的参数、作业题。

    1.函数的作用:封装代码.大量的减少了重复的代码. 2.全局空间:顶行写的就是全局空间. 图解 : 3.函数的定义: def 是一个关键字.申明要定义一个函数 my_len 函数的名字.遵循变量命名的 ...

  2. python27期day11:f-strings格式化、迭代器、生成器、作业题。

    1.建议小写f: name = "宝元"age = 18sex = "男"msg = F"姓名:{name},性别:{age},年龄:{sex}&qu ...

  3. 企业建站系统MiinCMP1.0.5 标准版公布!

    2014-5-6日,Juuluu公布其企业建站系统MiinCMP1.0.5 标准版,1.0.5是一款相对成熟的企业站点解决方式.执行MiinCMP1.0.5,仅仅需2M的mysql,50m的java空 ...

  4. day13 闭包及装饰器

    """ 今日内容: 1.函数的嵌套定义及必包 2.global 与 nonlocal 关键字 3.开放封闭原则及装饰器 """ " ...

  5. python27期day14:有参装饰器、多个装饰器装饰一个函数、递归、作业题

    1.有参装饰器:给装饰器添加一个参数.来控制装饰器的行为. @auth(参数) auth里层的函数名 = auth(参数) 被装饰的函数名 = auth里层的函数名(被装饰的函数名) 被装饰的函数名( ...

  6. Python 闭包、迭代器、生成器、装饰器

    Python 闭包.迭代器.生成器.装饰器 一.闭包 闭包:闭包就是内层函数对外层函数局部变量的引用. def func(): a = "哈哈" def func2(): prin ...

  7. Python入门-装饰器初始

    今天我们就围绕一个来展开,那就是:装饰器 一.装饰器 在说装饰器之前,我们先说一个软件设计的原则:开闭原则,又被称为开放封闭原则,你的代码对功能的扩展是开放的,你的程序对修改源代码是封闭的,这样的软件 ...

  8. Python脱产8期 Day13 2019/4/28

    一 函数的嵌套定义 1在一个函数的内部定义另一个函数. 2.为什么有函数的嵌套定义: # 1)函数fn2想直接使用fn1函数的局部变量,可以讲fn2直接定义到fn1的内部,这样fn2就可以直接访问fn ...

  9. PYTHON-有参装饰器,无参装饰器,语法糖

    装饰器 装饰器就是闭包函数的一种应用场景 一 为何要用装饰器 #开放封闭原则:对修改封闭,对扩展开放 二 什么是装饰器 装饰器他人的器具,本身可以是任意可调用对象,被装饰者也可以是任意可调用对象. 强 ...

随机推荐

  1. CF707D Persistent Bookcase

    CF707D Persistent Bookcase 洛谷评测传送门 题目描述 Recently in school Alina has learned what are the persistent ...

  2. LG3119 「USACO2015JAN」Grass Cownoisseur

    问题描述 LG3119 题解 显然,如果有个环,一定是全部走完的. 所以缩点,缩出一个 \(\mathrm{DAG}\) . 只能走一次反向,于是在正图和反图上各跑一次,枚举边,取 \(\mathrm ...

  3. Django CSRF

    CSRF(Cross-site request forgery)跨站请求伪造 django为用户实现防止跨站请求伪造的功能,通过中间件 django.middleware.csrf.CsrfViewM ...

  4. nodejs 连接MySQL后,输出数据带有RowDataPacket、中括号大括号怎么去掉?

    var mysql = require('mysql'); var connection = mysql.createConnection({ host : 'localhost', user : ' ...

  5. Educational Codeforces Round 63 (Rated for Div. 2) E 带模高斯消元

    https://codeforces.com/contest/1155/problem/E 题意 \(f(x)=a_0+a_1x+a_2x^2+...+a_kx^k,k \leq 10,0 \leq ...

  6. 正睿暑期培训day3考试

    链接 A 可以发现一个小棍的贡献是使得左右两列上的球位置互换.所以只要找出哪两个球会经过当前位置,然后swap一下就行了.. 考场上调了2.5h,依然没过样例.赛后发现忘了排序!!!!... /* * ...

  7. 领域驱动设计(DDD)编码实践

    写在前面 Martin Fowler在<企业应用架构模式>一书中写道: I found this(business logic) a curious term because there ...

  8. 在net Core3.1上基于winform实现依赖注入实例

    目录 在net Core3.1上基于winform实现依赖注入实例 1.背景 2.依赖注入 2.1依赖注入是什么? 2.1依赖注入的目的 2.2依赖注入带来的好处 2.2.1生命周期的控制 2.2.2 ...

  9. npm ERR! Cannot read property 'resolve' of undefined

    一 .有可能是版本过低,或者软件损坏,重新安装一下试试 地址

  10. HTML连载17-id选择器&类选择器

    一.问题:我们前面讲了标签选择器有一个缺陷就是它不加选择的把所有相同的标签全都变成统一样式,这对于我们个性化定制产生了阻碍,因此我们便引出了id选择器,来进行特别指定进行配置样式 二.id选择器 1. ...