装饰器:
定义:本质是函数,(装饰其他的函数)就是为其他函数添加附加功能
原则:1.不能修改被装饰的函数的源代码
2.不能修改被装饰的函数的调用方式
实现装饰器的知识储备
1,函数即“变量”
2,高阶函数
a:把一个函数名当做实参传给另一个函数
b:返回值包含函数名
3,嵌套函数
高阶函数+嵌套函数==装饰器
import time def timemer(func): def wrapper(*args,**kwargs): start_time=time.time() func(*args,**kwargs) stop_time=time.time() print(‘the func run time is %s‘ %(stop_time-start_time)) return wrapper @timemer def test(name): time.sleep(1) print(‘in zhe test1 %s‘ %(name)) test("nihao")
上面代码可以看到运行test函数时 其实是去运行上面的timemer装饰器的内部wrapper函数了 真正执行test函数是在wrapper内部的func()这个函数运行
列表生成式
a=[i*2 for i in range(10)]
生成器
通过列表生成式,我们可以直接创建一个列表,但是,受到内存限制,列表的容量肯定是有限的,而且
创建一个包含100万个元素的列表,不就占用很大的内存空间,如果我们仅仅需要访问前面几个元素
那后面的绝大数元素占用的空间就白白浪费了
所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?
这样就不必创建完整的list,从而节省大量的空间,在python中,这种一边循环一边计算的机制,成为生成器
generator
要创建一个generator 有很多方法。第一种方法很简单,只要把一个列表生成式的[]改成()就创建了一个
生成器 generator
生成器只有调用的时候才生成数据
1 a=(i*2 for i in range(10)) 2 print(a) 3 for i in a: 4 print(i) 5 6 """ 7 可以将函数变成生成器 8 9 """ 10 def fib(max): 11 n,a,b=0,0,1 12 while n<max: 13 14 a,b=b,a+b 15 n+=1 16 yield b 17 18 # 前面的两个数相加等于这个数本身 19 for i in fib(10): 20 print(i)
生成器 并行运算
函数内加入 yield 可变成类似生成器的样子终止运行,__next__()可以执行下一句,yield 可以接收 send()传入的参数
import time def consumer(name): print("%s 准备吃包子啦" %name) while True: baozi=yield print("包子[%s]来了,被[%s]吃了" %(baozi,name)) def producter(name): c=consumer(‘A‘) c2=consumer(‘b‘) c.__next__() c2.__next__() print("老子开始准备做包子啦") for i in range(10): time.sleep(1) print("做了两个包子") c.send(i) c2.send(i) producter("大牛")
import time def fib(max): n,a,b=0,0,1 while n<max: time.sleep(1) a,b=b,a+b n+=1 yield b # 前面的两个数相加等于这个数本身 data=fib(10) print(data.__next__()) print(data.__next__()) print(data.__next__()) print(data.__next__()) print("做点其他事情看看") print(data.__next__()) print(data.__next__()) print(data.__next__()) print(data.__next__()) print(data.__next__()) print(data.__next__())
迭代器
我们已经知道,可以直接作用于for
循环的数据类型有以下几种:
一类是集合数据类型,如list
、tuple
、dict
、set
、str
等;
一类是generator
,包括生成器和带yield
的generator function。
这些可以直接作用于for
循环的对象统称为可迭代对象:Iterable
。
可以使用isinstance()
判断一个对象是否是Iterable
对象:
1
2
3
4
5
6
7
8
9
10
11
|
>>> from collections import Iterable >>> isinstance ([], Iterable) True >>> isinstance ({}, Iterable) True >>> isinstance ( ‘abc‘ , Iterable) True >>> isinstance ((x for x in range ( 10 )), Iterable) True >>> isinstance ( 100 , Iterable) False |
而生成器不但可以作用于for
循环,还可以被next()
函数不断调用并返回下一个值,直到最后抛出StopIteration
错误表示无法继续返回下一个值了。
*可以被next()
函数调用并不断返回下一个值的对象称为迭代器:Iterator
。
可以使用isinstance()
判断一个对象是否是Iterator
对象:
1
2
3
4
5
6
7
8
9
|
>>> from collections import Iterator >>> isinstance ((x for x in range ( 10 )), Iterator) True >>> isinstance ([], Iterator) False >>> isinstance ({}, Iterator) False >>> isinstance ( ‘abc‘ , Iterator) False |
生成器都是Iterator
对象,但list
、dict
、str
虽然是Iterable
,却不是Iterator
。
把list
、dict
、str
等Iterable
变成Iterator
可以使用iter()
函数:
1
2
3
4
|
>>> isinstance ( iter ([]), Iterator) True >>> isinstance ( iter ( ‘abc‘ ), Iterator) True |
你可能会问,为什么list
、dict
、str
等数据类型不是Iterator
?
这是因为Python的Iterator
对象表示的是一个数据流,Iterator对象可以被next()
函数调用并不断返回下一个数据,直到没有数据时抛出StopIteration
错误。可以把这个数据流看做是一个有序序列,但我们却不能提前知道序列的长度,只能不断通过next()
函数实现按需计算下一个数据,所以Iterator
的计算是惰性的,只有在需要返回下一个数据时它才会计算。
Iterator
甚至可以表示一个无限大的数据流,例如全体自然数。而使用list是永远不可能存储全体自然数的。
小结
凡是可作用于for
循环的对象都是Iterable
类型;
凡是可作用于next()
函数的对象都是Iterator
类型,它们表示一个惰性计算的序列;
集合数据类型如list
、dict
、str
等是Iterable
但不是Iterator
,不过可以通过iter()
函数获得一个Iterator
对象。
Python的for
循环本质上就是通过不断调用next()
函数实现的,例如:
1
2
|
for x in [ 1 , 2 , 3 , 4 , 5 ]: pass |
实际上完全等价于:
# 首先获得Iterator对象: it = iter([1, 2, 3, 4, 5]) # 循环: while True: try: # 获得下一个值: x = next(it) except StopIteration: # 遇到StopIteration就退出循环 break
内置函数
#!/usr/bin/env/python # -*- coding:utf-8 -*- # Author:wanghui """ # 返回绝对值 """ print(abs(-3)) """ all(iterable) 判断可迭代对象中所有元素是否为真 """ print(all([0,-1,3])) """ #any(iterable) 判断可迭代对象中所有元素中只要有一个为真 就为真 """ print(any([0,0,0,1])) """ ascii 返回ascii码 并且返回的是字符串形式 """ print(ascii("你好")) print(ascii([1,2,"开外挂"])) """ bin 将十进制转换成二进制 """ print(bin(2)) """ bool 判断真假 """ print(bool("")) """ bytes 将字符串转换成二进制字符, 字符串无法修改的 但是可以通过bytearray 将其转换成字符列表 就可以进行修改了 """ a=bytes("abcde王辉",encoding="utf-8") print(a) b=bytearray("abcdef",encoding="utf-8") b[0]=100 print(b) """ chr 输入数字 打印出对应的ascii字符 """ print(chr(97)) """ ord 输入字符,打印出对应的ascii字符的数字 """ print(ord("a")) """ compile """ code="for i in range(10):print(i)" print(code) c=compile(code,‘‘,‘exec‘) """ exec可以执行的函数 """ exec(c) """ eval使用比较简单 """ print(eval("1+2")) """ 匿名函数 lambda 可以处理简单的函数 """ calc=lambda n:print(n) calc("lambda函数") """ filter 一般和lambda 结合使用 过滤 """ res=filter(lambda n:n>5,range(10)) for i in res: print(i) """ 和lambda 结合的还有map """ res=map(lambda n:n*n,range(10)) for i in res: print(i) """ 和lambda 结合的还有 reduce """ import functools res=functools.reduce(lambda x,y:x+y,range(10)) print(type(res),res) """ frozenset 将集合变成不可更改的 """ a=set([1,4,33,212,33,33,12,4]) print(a) a.add(3) print(a) a=frozenset(a) """ globals 打印出全部的变量 以键值对形式表示 """ print(globals()) """ hex 转换成十六进制 """ print(hex(17)) """ locals 打印出局部的变量 """ def abd(): s=2 print(locals()) abd() """ max()取最大数值 """ print(max(1,2,3,4,5)) """ min()取最小数值 """ print(min(1,23,4,5,6)) """ oct将数值转换成八进制 """ print(oct(8)) """ pow 求数值的多少次方 和 x**y 一样的结果 """ print(pow(2,10)) print(2**10) """ round() 将小数点后取几位 """ print(round(2.1234,1)) """ sorted()排序 """ a={1:2,3:5,11:325,32:5} print(sorted(a.items(),key=lambda x:x[1])) """ zip() 中文意思就是拉链 将两个列表连在一起 """ a=[1,2,3,4,5,6] b=[‘a‘,‘b‘,‘c‘,‘d‘] for i in zip(a,b): print(i)