闭包

1, 闭包是嵌套在函数中的

2, 闭包是内层函数对外层函数的变量(非全局变量)的引用(改变)

3,闭包需要将其作为一个对象返回,而且必须逐层返回,直至最外层函数的返回值

闭包例子:

def a1():
name = 'wk'
def a2():
print(name)
return a2

闭包函数的作用

非闭包函数:随着函数的结束临时空间关闭

def func1(s):
n = 1
n += s
print(n)
func1(3)
func1(3) #每次函数结束临时空间关闭
func1(3) 4
4
4

闭包函数 :不会随函数结束释放内存空间

def func1(s):
n = 1
def cc():
nonlocal n
n += s
print(n)
return cc
func1(2)()
func1(2)()
func1(2)()
cd = func1(2) #cd = func1(2) 既将cc = cd,接下来的cd一直在跑的是cc()函数,而非从上往下依次跑,且不会随函数结束释放内存空间
cd()
cd()
cd() 3
3
3
3
5
7

装饰器

装饰器:给函数增加一个新功能:

例:需要写一个功能,测试函数的执行效率

import time                   #需要测试的函数
def aa():
print(111)
time.sleep(1)
aa()

low方法:

import time                     #重复造轮子,测试函数的效率 必须得复制代码,
def aa():
start = time.time()
print(111)
time.sleep(1)
end = time.time()
print('执行了%s秒' %(start - end))
aa() 111
执行了-1.0003249645233154秒

增加需求对N个函数都要操作:

import time                         #改变了函数的调用方式
def aa():
print(111)
time.sleep(1) def cc(xx): #将被测试的函数名当做参数传入
start = time.time()
xx()
end = time.time()
print('执行了%s秒' %(start - end)) cc(aa) #执行cc即可测试N个函数 111
执行了-1.000324010848999秒

用最少的代码,解决调用方式一致性的问题(不改变源代码的调用方法)。

import time
def aa():
print(111)
time.sleep(1) def cc(xx):
def inner():
start = time.time()
xx()
end = time.time()
print('执行了%s秒' %(start - end))
return inner
aa = cc(aa)
aa() 111
执行了-1.0004630088806152秒

最终基础版 python提供一个机制,优化,语法糖 @

import time
def cc(xx):
def inner():
start = time.time()
xx()
end = time.time()
print('执行了%s秒' %(start - end))
return inner @cc # @cc 为 aa = cc(aa)
def aa():
print(111)
time.sleep(1)
aa() 111
执行了-1.0007429122924805秒

装饰器本质其实闭包,装饰器在不改变原函数的内部函数体以及调用方式的前提下,给函数增加了额外的功能:登录,注册,打印日志,函数效率等等。

装饰器传参

def func(f1):
def aa(x):
s1 = time.time()
f1(x)
print(time.time() - s1)
return aa @func
def dd(x):
time.sleep(2)
print("来了老弟 %s" %(x))
dd(111)
来了老弟 111
2.0003223419189453

装饰器多个参数传参

import time
def func(f1):
def aa(*args, **kwargs):
s1 = time.time()
f1(*args, **kwargs)
print(time.time() - s1)
return aa @func
def dd(a, b, c):
time.sleep(2)
print("来%s 老弟 %s %s" %(a,b,c)) dd('wk', 25, 'xixi')

来wk 老弟 25 xixi
2.000187635421753

被装饰的函数有返回值

import time
def func(f1):
def aa(*args, **kwargs):
s1 = time.time()
s2 = f1(*args, **kwargs)
print(time.time() - s1)
return s2
return aa
@func
def dd(a, b, c):
time.sleep(2)
print("来%s 老弟 %s %s" %(a,b,c))
return 111
print(dd('wk', 25, 'xixi'))

来wk 老弟 25 xixi
  2.000335693359375
  111

简单的博客园登陆

login_status = {
'username': None,
'status': False,
}
def login(x):
def aa():
if login_status['status']:
x() else:
user = input("请输入用户名")
passwd = input('请输入密码')
if user == 'wk' and passwd == '':
print('登陆成功')
login_status['username'] = user
login_status['status']= True
x()
return aa
@login
def wenzhang():
print('欢迎访问文章页面')
@login
def riji():
print('欢迎访问日记界面')
@login
def pinglun():
print('欢迎来到评论界面')
dic = {
1: login,
2: wenzhang,
3: riji,
4: pinglun,
}
while 1:
print('''
欢迎来到博客园首页:
1,登录
2.文章页面
3.日记页面
4.评论页面
''')
num = input('请输入数字')
dic[int(num)]()

装饰及进阶,带参数的装饰器

def aa(a,b):
def bb(x):
def cc():
x()
print(a,b)
return cc
return bb
@aa(1,2) #aa(1,2)获得 bb的返回值,aa()= bb @bb为装饰器
def dd():
print(111)
dd() 111
1 2

多个装饰器装饰一个参数

def aa1(func):    # func = 函数名f
def inner1():
print('wrapper1 ,before func') # 2
func() # 函数f
print('wrapper1 ,after func') # 4
return inner1 def aa2(func):   # func = inner1
def inner2():
print('wrapper2 ,before func') # 1
func() # inner1()
print('wrapper2 ,after func') # 5
return inner2 @aa2 #f = aa2(f.) f. = infner1(f)
@aa1 # f = aa1(f) 里面的f是函数名f 外面的f是 inner1
def f():
print('in f') # 3
f() # inner2

  wrapper2 ,before func
  wrapper1 ,before func
  in f
  wrapper1 ,after func
  wrapper2 ,after func

多个装饰器就近执行先执行@aa1在执行@aa2 ,@aa1为 f = aa1(f)= inner1并将f作为参数传进去,此时inner1里的f = print('in f').

在执行@aa2  @aa为 f =aa2(f) = inner2 并将f 作为参数传进去,此时inner2里的 f = inner1

因此在执行时,f = inner2  输出步骤为:

1. 先执行inner2的 ”wrapper2 ,before func“

2执行f()    f()=inner1()   = "wrapper1 ,before func",“in f”,"wrapper1 ,after func"    (inner1里的f为print('in f')

3.执行inner2的“wrapper2 ,after func”

迭代器

可迭代对象

可迭代对象: 内部含有"__iter__"方法的数据就是可迭代对象,像list str tuple set dict range() 文件句柄 都是可迭代对象

s1 = '嘣沙卡拉卡'
print('__iter__' in dir(s1)) #判断s1是否是可迭代对象
True

迭代器

内部含有"__iter__"方法的并且含有"__next__"方法的就是迭代器 (列表是可迭代对象却不是迭代器)

f1 = open('regsiter', encoding='utf-8')
print('__iter__' in dir(f1))
print('__next__' in dir(f1)) True
True

迭代器:next -->一次取一个值

l1 = [1, 2, 3, 4]
l2 = iter(l1)
print(l2.__next__())
print(l2.__next__())
print(l2.__next__())
print(l2.__next__()) 1
2
3
4

列表是可迭代对象却不是迭代器

lst = [,,]
print(dir(lst)) ['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__',
'__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__',
'__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__',
'__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__',
'__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert',
'pop', 'remove', 'reverse', 'sort'] #迭代器里没有 __next__方法,因此不是迭代器 进程已结束,退出代码
lst = [,,]
t1 = lst.__iter__() #此时t1就是一个迭代器
print(t1.__next__()) #迭代t1用__next__方法 得到1

迭代器:

  1.可以非常非常节省内存

  2.满足惰性机制.

  3.一条路走到黑.

利用while循环模拟for循环的机制.

1.将可迭代对象转化为迭代器

2.利用next进行取值

3.利用异常处理终止循环

l1 = [1, 2, 3, 4]
l2 = iter(l1)
while 1:
try:
print(l2.__next__())
except StopIteration:
break 1
2
3
4

生成器

生成器内部保存的是代码而不是数据

函数式写法构建生成成器

def cc1():
yield 1 #只要函数中出现yield,那么他就不是函数了,他是生成器函数.
yield 2
yield 3
yield 4
c1 = cc1() #生成器对象
print(c1.__next__())
print(c1.__next__())
print(c1.__next__())
print(c1.__next__()) 1
2
3
4

return和yield 的区别

return结束函数,给函数返回值

yield 不会结束生成器函数,next对应一个yield进行取值

def aa():                       #生成器的好处,按需去取,需要多少取多少,并记录取到哪了
for i in range(40):
yield '这是数字%s' % (i)
a1 = aa()
for i in range(5):
print(a1.__next__()) 这是数字0
这是数字1
这是数字2
这是数字3
这是数字4

send()也可以像__next__()一样执行生成器中的代码,都是执行到下一个yield

send()可以给上一个yield传值  ,第一次运行没有yield的传值,所以只能用于next之后.

def aa():
print('')
a = yield ''
print(a)
print('')
b = yield ''
print(b)
gen = aa()
print(gen.__next__())
print(gen.send('')) #遇到send 可将上个yield的值改为send里的参数, 并执行到下一个yield结束

yield from

def aa():
yield from [, , , ]
yield from [, , , ]
cc = aa()
print(cc.__next__())
print(cc.__next__())
print(cc.__next__())
print(cc.__next__())
print(cc.__next__())

列表推导式

生成一个1到100的列表:

l1 = [i for i in range(1, 101)]
print(l1)
循环模式 [变量(加工后的变量) for 变量 in iterable]
筛选模式 [变量(加工后的变量) for 变量 in iterable if 条件]

循环模式:

l1 = ['python%s期' %(i) for i in range(1, 25)]
print(l1)
['python1期', 'python2期', 'python3期', 'python4期', 'python5期', 'python6期', 'python7期', 'python8期', 'python9期', 'python10期', 'python11期', 'python12期', 'python13期', 'python14期', 'python15期', 'python16期', 'python17期', 'python18期', 'python19期', 'python20期', 'python21期', 'python22期', 'python23期', 'python24期']

筛选模式

l2 = [i**2 for i in range(1,31) if i % 3 == 0]
print(l2)
[9, 36, 81, 144, 225, 324, 441, 576, 729, 900]

生成器表达式:  (i*i for i in range(1, 11))  用()括起来,其他规则和列表推导式一样

c1 = (i*i for i in range(1, 11))
for i in c1:
print(i)
1
4
9
16
25
36
49
64
81
100

列表推导式,生成器表达式:

优点:构造简单,一行完事

缺点:1.不能排错

   2.不能构建复杂的数据

字典推导式

lst = ['持国天王','广目天王','多闻天王','增长天王']
dic = {i:lst[i] for i in range(len(lst))}
print(dic) {: '持国天王', : '广目天王', : '多闻天王', : '增长天王'}

集合推导式

s = {i for i in range()}
												

python笔记3 闭包 装饰器 迭代器 生成器 内置函数 初识递归 列表推导式 字典推导式的更多相关文章

  1. python笔记-4(装饰器、生成器、迭代器)

    一.熟练掌握装饰器的原理 (在装饰器学习的过程中,查了看了很多资料,个人感觉走了很多的弯路,这个笔记,分享我的理解,希望能帮助到一些人.本文对装饰器的描述,侧重点是条理与逻辑思路,想通过从无到有的方式 ...

  2. python学习 day11 (3月16日)----(生成器内置函数)

    1生成器 1生成器的本质 一定是迭代器(反之不一定(用send(生成器特有方法)验证))2生成器是可以让程序员自己定义的一个迭代器3生成器的好处,节省内存空间4生成器的特性,一次性的,惰性机制,从上往 ...

  3. Python3基础(4)匿名函数、装饰器、生成器、迭代器、内置函数、json&pickle序列化、软件目录开发规范、不同目录间模块调用

    ---------------个人学习笔记--------------- ----------------本文作者吴疆-------------- ------点击此处链接至博客园原文------ 1 ...

  4. python第十二天 生成器,迭代器,内置函数

    第二模块学习:  生成器,迭代器,内置函数 生成器特点:只有在调用时才会生成相应的数据,运行的速度快! 示例: def fil(max):#斐波那契数 n,a,b=0,0,1 #定义初始数据 whil ...

  5. python迭代器的内置函数

    1.迭代器: 内置函数: (1)iter() -__iter__() (2)next() -__next__() 2.迭代器的举例; 对于Fibs数列,我们对其进行 限量输出: 实现代码如下: cla ...

  6. Python【map、reduce、filter】内置函数使用说明(转载)

    转自:http://www.blogjava.net/vagasnail/articles/301140.html?opt=admin 介绍下Python 中 map,reduce,和filter 内 ...

  7. Python【map、reduce、filter】内置函数使用说明

    题记 介绍下Python 中 map,reduce,和filter 内置函数的方法 一:map map(...) map(function, sequence[, sequence, ...]) -& ...

  8. Python学习笔记九:装饰器,生成器,迭代器

    装饰器 本质是函数,装饰其他函数,为其他函数添加附加功能 原则: 1不修改原函数的源代码 2不修改原函数的调用方式 知识储备: 1函数即变量 使用门牌号的例子说明函数,调用方式与变量一致 2高阶函数 ...

  9. Python中的装饰器,迭代器,生成器

    1. 装饰器 装饰器他人的器具,本身可以是任意可调用对象,被装饰者也可以是任意可调用对象. 强调装饰器的原则:1 不修改被装饰对象的源代码 2 不修改被装饰对象的调用方式 装饰器的目标:在遵循1和2的 ...

随机推荐

  1. zabbix-自定义监控项

    一.自定义一个监控项 模板虽好,但是不能解决所有的监控,有些需要的监控项在模板中并没有,需要我们自己定义一个监控项,如何定义一个监控项呢?大概的流程是这样的几步 .在插件配置文件中定义一个key/va ...

  2. Java入门学习总结_02

    一:注释 注释主要就是用来解释某句或者某段代码使得其他人调试更加方便.特点是在编译代码的时候不会编译注释, 不管发不发生错误.注释主要分为单行注释//(快捷键ctrl+/).多行注释/* */(快捷键 ...

  3. ARP、Proxy ARP、Gratuitous ARP

    Proxy ARP 什么是Proxy ARP? 一个主机A(通常是路由器)有意应答另一个主机B的ARP请求(ARP requests).主机A通过伪装其身份,承担起将分组路由到真实目的地的责任.代理A ...

  4. python读txt数据报编码错误

    读数据代码: with open(path,'r') as f: for line in f: line = line.strip() 报错: UnicodeDecodeError: 'gbk' co ...

  5. idou老师教你学Istio 19 : Istio 流量治理功能原理与实战

    一.负载均衡算法原理与实战 负载均衡算法(load balancing algorithm),定义了几种基本的流量分发方式,在Istio中一共有4种标准负载均衡算法. •Round_Robin: 轮询 ...

  6. Maven 发布项目到Jetty服务器———5

    官网: http://www.eclipse.org/jetty/documentation/current/jetty-maven-plugin.html 1.安装配置插件 2. 运行 命令: je ...

  7. mongoDB的基本操作之数据更新

    查询了解后,我们还要了解下如何进行数据的更新,在mongodb中,数据的更新是用update方法,update至少接收两个参数,一个是要查找的记录条件,一个是更新之后的数据,我们现在查找x为1的数据 ...

  8. 《JavaScript DOM编程艺术》(第二版)学习笔记(一)

    这本书去年就买了但一直没看,闲暇的时候看了下,发现里面写的内容还真是不错,所以决定一边在博客上记录些学习的笔记,以便以后观看及查找方便. js文件最好的做法是放在< body>标签里,这样 ...

  9. 【转】关于 Goroutine Channel Select 的用法和理解

    原文:https://blog.csdn.net/jfkidear/article/details/88661693 ----------------------------------------- ...

  10. 部署 & virtualen

    安装:apt-get install virtualen virtualenv --no-site-packages venv 加上了参数--no-site-packages,这样,已经安装到系统Py ...