一、装饰器
1、意义:当需要给程序中某些函数新增某项功能时,为了避免直接修改函数源代码和函数调用方式,所以引入装饰器。
2、定义:装饰器用于装饰其他函数,就是为其他函数提供附加功能。
3、原则:
1)不修改被装饰的函数的源代码
2)不修改被装饰的函数的调用方式
4、装饰器储备知识:
1)函数即变量
2)高阶函数
a.把函数当做参数传递给另一个函数(在不修改被修饰函数源代码的情况下为该函数添加功能)
b.返回值中包含函数名(在不修改被修饰的函数的调用方式的情况下为该函数添加功能)
3)嵌套函数:在函数体内重新声明一个新的函数
5、装饰器类型
1)不带参数函数的装饰器
#!/usr/bin/env python3 # -*- coding:utf-8 -*- # 定义装饰器 def decorator1(func): def deco(): print("Running test1!") func() print("Complete test1") return deco # 装饰不带参数的函数 @decorator1 def test1(): print("test 1") test1()
2)带参数的函数的装饰器
#!/usr/bin/env python3 # -*- coding:utf-8 -*- # 修饰带参数的函数 def decorator2(func): def deco(*args,**kwargs): print("这是\"%s\"的装饰器" % args) func(*args,**kwargs) return deco @decorator2 def test2(name): print("test 2,name:", name) test2("张三")
3)带参数的装饰器
#!/usr/bin/env python3 # -*- coding:utf-8 -*- # 带参数的装饰器 def decorator3(flage): def warrper(func): def deco(*args,**kwargs): if flage == 1: print("这个函数的flage是:" , flage) func(*args,**kwargs) else: print("这flage是个什么玩意儿?" , flage) func(*args,**kwargs) return deco return warrper 调用装饰器时传入参数 @decorator3(flage=3) def test3(name, age): print("test 3,name:%s,age:%s" % (name, age)) test3("李四",22)
6、关于装饰器的理解
1)不带参数的装饰器
装饰器在被装饰函数之前定义的时候,@装饰器名,此语法只是引用了装饰器函数,相当于对被装饰函数的函数名进行了重命名,例如:
def decorator1(func): def deco(): print("Running test1!") func() print("Complete test1") return deco # @decorator1等价于 test1 = decorator1(test1()),等价于test1 = deco,所以,test1()等价于deco() @decorator1 def test1(): print("test 1")
2)带参数的装饰器
def decorator3(flage): def warrper(func): def deco(*args,**kwargs): if flage == 1: print("这个函数的flage是:" , flage) func(*args,**kwargs) else: print("这flage是个什么玩意儿?" , flage) func(*args,**kwargs) return deco return warrper # @decorator3(flage=3)此处直接调用了decorator3函数,相当于@warrper @decorator3(flage=3) def test3(name, age): print("test 3,name:%s,age:%s" % (name, age))
二、生成器
1、列表生成式
python中可以通过列表生成式来快速生成列表,例如生成一个列表如下:
[1*1,2*2,3*3,......,100*100]
生成这个列表可以用for循环来依次append,但是代码会比较多,此时就可以使用列表生成式来生成这个列表:
>>> list1 = [x*x for x in range(1,101)] >>> list1 [1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 169, 196, 225, 256, 289, 324, 361, 400, 441, 484, 529, 576, 625, 676, 729, 784, 841, 900, 961, 1024, 1089, 1156, 1225, 1296, 1369, 1444, 1521, 1600, 1681, 1764, 1849, 1936, 2025, 2116, 2209, 2304, 2401, 2500, 2601, 2704, 2809, 2916, 3025, 3136, 3249, 3364, 3481, 3600, 3721, 3844, 3969, 4096, 4225, 4356, 4489, 4624, 4761, 4900, 5041, 5184, 5329, 5476, 5625, 5776, 5929, 6084, 6241, 6400, 6561, 6724, 6889, 7056, 7225, 7396, 7569, 7744, 7921, 8100, 8281, 8464, 8649, 8836, 9025, 9216, 9409, 9604, 9801, 10000]
2、生成器
上述列表生成式生成的列表都完全生成后保存在内存中,如果该列表数据量特别大的时候,有可能会导致内存打满,而且如果需要遍历该变量或者使用某值时,完全创建列表会白白浪费大量的内存空间。生成器的出现就是为了解决这个问题。
生成器只有在调用时才会生成相应的数据,生成器只保存当前的元素。
# 创建生成器 >>> g = (x*x for x in range(10)) >>> print(g) <generator object <genexpr> at 0x1012e0ba0> # 遍历生成器 >>> for i in g: ... print(i) ... 0 1 4 9 16 25 36 49 64 81 >>>
3、next()方法和__next__()方法
next()方法和__next__()方法可以返回生成器的下一个值
>>> g = (x*x for x in range(10)) >>> g.__next__() 0 >>> next(g) 1 >>> g.__next__() 4 >>> next(g) 9 >>>
4、yield语句
通过yield语句可以使一个函数变成一个生成器,只需要把想输出的值变成yield来输出就可以
#!/usr/bin/env python3 # -*- coding:utf-8 -*- # 此时的函数就是一个生成器了 def fib(max): n, a, b = 0, 0, 1 while n < max: # print(b) # 用yield替换print()就变成了生成器 yield b a,b = b,a+b n += 1 return ‘done‘ f = fib(10) for i in f: print(i)
5、try语句
#!/usr/bin/env python3 # -*- coding:utf-8 -*- def fib(max): n, a, b = 0, 0, 1 while n < max: # print(b) yield b a,b = b,a+b n += 1 return ‘done‘ f = fib(10) while True: try: x = next(f) print(x) except StopIteration as error: print("超过了生成器最大的限制!",error.value) break
6、使用yield实现协程并发
#!/usr/bin/env python3 # -*- coding:utf-8 -*- import time def eat(name): print("%s 准备抢包子吃了!"% name) while True: baozi = yield print("%s包子被%s吃了!" % (baozi,name)) def pro(name): print("%s开始做包子了!!!" % name) user1 = eat("张三") user2 = eat("李四") user1.__next__() user2.__next__() for i in range(10): time.sleep(1) # send()方法,send()方法会向yield返回值 user1.send(i) user2.send(i) pro("王五")
三、迭代器
1、直接作用于for循环的对象统称为可迭代对象,可以使用isinstance()方法判断是否是可迭代对象Iterable
2、可以被next()函数调用并不断返回下一个值的对象统称为迭代器Iterator
3、使用iter()方法可以把可迭代对象变成一个迭代器
四、内置方法
abs():取绝对值 all(Iterable):可迭代对象中所有元素都是真则返回True,反之返回False any(Iterable):可迭代对象中只要有一个元素为真则返回True,反之返回False ascii(object): bin(整数):把一个十进制整数转换为二进制 bool():判断真假 bytearray():将一个byte类型的字符串变成可修改字符串 bytes() callable(参数):判断参数是否可调用 chr(整数):返回对应整数的unicode对应的字符 ord(字符):返回字符对应的unicode中的数字 compile(codestr,‘文件名‘,‘模式‘):将代码当做字符串编译成一个 dir(object):查看对象的方法 divmod(num1,num2):返回num1除以num2的商和余数 eval(): exec(): filter(func,Iterable):从一组可迭代对象中根据func函数的规则返回结果,func可以用lambda匿名函数 map(func,Iterable):把可迭代对象中所有值传递给func处理 frozenset():把集合变为不可变集合 globals():返回整个程序的所有的变量名和值 hash(): hex(数字):转换为16进制 locals():打印局部变量 max():返回列表中最大值 min():返回列表中最大值 oct(数字):十进制转二进制 power(x,y):x的y次方 repr():通ascii round(float,num):保存num位浮点数 slice():切片 sorted(dict):排序,默认按key排序 sum(list):列表求和 __import__(‘str‘):使用字符串导入模块
五、匿名函数
lambda表达式:
lambda arguement1,arguement2,...,arguementn:expression
>>> lambda x:x**5 <function <lambda> at 0x1013dae18> >>> a = lambda x:x**5 >>> a(5) 3125 >>> a(3) 243 >>>
六、json和pickle数据序列化
1、json介绍
json用于不同语言之间的数据交互,采用键值对的方式记录数据,使用json时需要先导入json模块
2、json序列化
json.dump(数据,文件句柄)
f.write(json.dumps(数据))
#!/usr/bin/env python3 # -*- coding:utf-8 -*- import json date = { "name":"zhangsan", "age":30, "JOB":"IT" } with open("json.txt","w") as f: json.dump(date,f)
#!/usr/bin/env python3 # -*- coding:utf-8 -*- import json date = { "name":"zhangsan", "age":30, "JOB":"IT" } with open("json.txt","w") as f: f.write(json.dumps(date))
3、json反序列化
json.loads(数据)
json.load(文件句柄)
#!/usr/bin/env python3 # -*- coding:utf-8 -*- import json with open("json.txt","r") as f: date = f.read() date = json.loads(date) print(type(date)) print(date)
#!/usr/bin/env python3 # -*- coding:utf-8 -*- import json with open("json.txt","r") as f: date = json.load(f) print(type(date)) print(date)
序列化的时候只dump一次,也只load一次。