day04 装饰器 迭代器&生成器 Json & pickle 数据序列化 内置函数

回顾下上次的内容

转码过程:
先decode  为 Unicode(万国码 ) 然后encode 成需要的格式
 
 
3.0 默认是Unicode  不是UTF-8
所以不需要指定  如果非要转为UTF-8  就再指定
变量的查找顺序:
1 从里往外找,先找自己本地的local  没有就会去上一级找,直到找到此变量,
 
 
全局变量不能在函数里改变指的是纯字符的,
list 及字典等会改变

 

函数递归:
 
一层一层进去,
return 一层一层出来
 
特点:
# 明确的结束条件
# 问题规模每递归一次都应该比上一次的问题规模有所减少
# 效率低
 
 
高阶函数:
把一个函数当作另一个函数的值传进去
 
 
函数式编程:
1 真正的函数式编程是没有变量的,是什么就是什么
2 没有副作用,传入的参数是什么结果就是一定的
 
 
 
文件打开方式:
基本: r w a
其他: r+ 是追加  w+ 写读,基本没用  a+ 追加写读
           rb 二进制模式打开,是bytes 模式   wb 二进制  ab
   

 下面开始讨论装饰器

装饰器:
 
本质: 是函数
作用: 是装饰其他函数,就是为其他函数添加附加功能

先写一个基础函数:

当我们需要给基础函数增加功能时,有以下三种方法:
1 修改函数代码,添加功能
2 定义一个函数,把新函数添加到旧的函数中
3 使用装饰器(最好)
 
但是:
生产环境中,函数一旦写好了原则上是不能修改函数的

所以装饰器的原则:

1 不能修改被装饰的函数的源代码
2 不能修改被装饰的函数的调用方式
 
实现装饰器知识储备:
1 函数即“变量”
2 高阶函数
3 嵌套函数
 
最终: 高阶函数+嵌套函数 ==》装饰器

先来看函数式怎么定义,怎么运行的:

函数只有在调用运行的时候才会去找定义的函数:

下面的例子是可以运行的:

 

 函数体 就是一堆字符串,没有任何功能,我们在定义的时候只是把这一堆字符串放到了一个内存空间里。

 

这里说一下解释器回收内存的机制:

门牌号没有的情况下就会清理房间

当门牌号没有的时候就是没有人再找这个房间的时候,就可以清理房间

当然也有匿名函数:

没有引用,立刻删除

 

什么叫做高阶函数:
 1  把一个函数名当作实参传给另外一个函数
 2  返回值中包含函数名

 

 高阶函数的使用案例:

 

实现的装饰器的功能但是修改了调用方式
在生产中是不可以修改调用方式的,因为你自己可以修改,但是别人调用的就不能修改了
嵌套函数:
在函数体里用def 定义一个内部的函数,只是调用的话就不叫嵌套函数,要有return 值

 

所以是这样写的:

说到这里我们要复习一下作用域:

 真正开始装饰器:

 

  把deco的内存地址赋予给原来的函数,再运行deco 函数

总结一下:

嵌套函数 return  用来实现不改变函数引用方式
高阶函数 用来实现新增功能
想要装饰哪个函数就写到哪个函数的前面
语法糖  @

 装饰器的传入参数:

 

适应所有的传参:
装饰器: 有参数没有参数,有多少参数都行。

 

实践:  这种的装饰器可以满足日常90% 的需求了。

 1 #!/usr/bin/env python3
 2 # Auth: Shen Yang
 3 import time
 4 #基础
 5 #-------------------
 6 def test1():
 7     time.sleep(2)
 8     print("in the test1")
 9 #test1()
10 def test2(name):
11     print("hehe",name)
12 #test2()
13 #-------------------
14 #定义一个装饰器函数
15 def timer(func):  #定义一个传入参数
16     def deco(*args,**kwargs):   #定义一个内嵌函数,实现新功能
17         start_time = time.time()
18         func(*args,**kwargs)
19         stop_time = time.time()
20         print("The func run time is {_time}".format(_time=stop_time-start_time))
21     return deco  #返回deco 临时函数的内存地址,从外面调用
22 @timer  #test1 =timer(test1)
23 def test1():
24     time.sleep(2)
25     print("in the test1")
26 @timer #test2 =timer(test2("Wang Lu"))
27 def test2(name):
28     print("hehe",name)
29 test1()
30 test2("Wang Lu")

迭代器&生成器
 
 
列表生成式
 
一句搞定三句的列表生成式

还可以使用函数 
 

把列表生成器变成一个生成器

 

 

必须循环到我的时候才会生成,所有不支持像列表那样直接选择第多少个
不然就会报错

 

生成器特点:
1 只有在调用时才会生成相应的数据
2 只记住当前的位置,不能往回返,因为前面的已经没有了,只能一个一个走
#1 只能通过for 循环
 
生成器的方法:
只有一个方法,取下一个
c.__next__()    #2.7 里是 next()  

 

把函数改为生成器:

 

 异常处理:

 

只要有yield 存在就是一个生成器
return  作用就是有异常的时候返回异常
实践:
列表生成器

 

生成器

 

方法:
1 list2 = (i*3 for i in range(10))
2 print(list2.__next__())
3 print("chulai1")
4 print(list2.__next__())
5 print("chulai2")
6 print(list2.__next__())
7 print("chulai3")
8 print(list2.__next__())

函数:

1 def gent(max):
2     n,a,b = 0,0,1
3     while n < max:
4         print(b)
5         a,b = b,a + b
6         n = n + 1
7     return "Over"
8 gent(10)

变成生成器:

 1 def gent(max):
 2     n,a,b = 0,0,1
 3     while n < max:
 4         yield (b)
 5         a,b = b,a + b
 6         n = n + 1
 7     return "Over"
 8 flb = gent(10)
 9 print(flb.__next__())
10 print(flb.__next__())
11 print(flb.__next__())
12 print(flb.__next__())

使用return 返回错误:

 1 def gent(max):
 2     n,a,b = 0,0,1
 3     while n < max:
 4         yield (b)
 5         a,b = b,a + b
 6         n = n + 1
 7     return "Over"
 8 flb = gent(10)
 9 while True:
10     try:
11         a = flb.__next__()
12         print("this is ",a)
13     except StopIteration as err:
14         print("Error in ",err.value)
15         break

yield 保存了函数的中断状态
 
给yield 传值 使用  send("韭菜陷")
唤醒yield 同事给yield 传值
__next__  只是唤醒
 

实践:
1 def consumer(name):
2 print("{_name}准备吃包子哈".format(_name=name))
3 while True:
4 baozi = yield
5 print("做出了{_baozi}的包子,被{_name}吃啦".format(_baozi=baozi,_name=name))
6  
7 c = consumer("Wanglu")
8 c.__next__()
9 c.send("韭菜馅") #和__next__ 效果一样,但是给 yield 传入了参数

 1 import time
 2 def consumer(name):
 3     print("{_name}准备吃包子哈".format(_name=name))
 4     while True:
 5         baozi = yield
 6         print("做出了{_baozi}的包子,被{_name}吃啦".format(_baozi=baozi,_name=name))
 7 def producer():
 8     c = consumer("王璐")
 9     c1 = consumer("申嘉锐")
10     c.__next__()
11     c1.__next__()
12     print("开始做包子了!!!")
13     for i in range(1,10):
14         time.sleep(1)
15         print("做了个包子,分两半来吃吧")
16         c.send(i)
17         c1.send(i)
18 producer()

上面的是最简单的协程
异步IO 模型  eoppll
 
 
 
迭代器:

 

简单的理解: 可迭代就是可循环的对象
 
判断是否可迭代

迭代器 和 可迭代对象 不是一回事

 把 list  dic  str 变为迭代器

for 循环 中的range 实质就是迭代器
读取文件的line 实质就是迭代器
 
 
内置方法:

 

abs()  取绝对值
all()  所有都为真返回真

 any()  任意一个为真就返回真,如果为空返回False

 ascii() 吧内存的对象转换为可打印的字符串

 bin() 十进制整数转为二进制   有用

bytes()

bytearray() 可修改的二进制

callable() 判断是否可调用

chr() 返回aiscll 码对应的字符

ord() 返回aiscll 位置对应的序号

compile()

直接 exec() 就可以执行字符串,上面的不用了
 
dir()  查看对象可使用的方法
 
divmod()   返回商和余数
evel()  执行 加减乘除 有语句不能用
 
exec() 执行语句
 
 
匿名函数  当一个功能只需要调用一次的时候就使用匿名函数,用完就删除
以下效果一模一样:
不支持for  和判断,只能写三元运算

filter() 一组数据中过滤出满足条件数据。

map() 对传入的每一个值进行处理,返回相应的结果   和列表生成器 一样的

 reduce()  需要import functools

frozenset()  编程一个不可变集合

globals()  以key value 形式返回整个文件中变量

hash()   同过一系列算法变成一个固定的表
max()  返回最大值
min()  返回最小值
 
next()  ==== 》 __next__
 
object
python 一切皆对象
一个对象有属性,有方法
列表,字符串,一切 都是对象,通过. 来调用方法

hex() 16进制转换

 oct()  8进制转换
round() 保留小数点后几位
slice()  
sorted()  排序
默认按key 来排序

zip()  拉链,一拉就和到一起了

如果有多的或者少的按少的算:

__import__()  非常有用:   导入字符串的模块

json  序列化:
 
 
 
不标准的做法:

序列化:

 

反序列化:

 

json  只能处理简单的数据类型,如函数啊 类啊 就报错

pickle   
 
用法和json 一样,可以序列化所有数据类型
 
 
记住: 
只dump 一次,只load 一次
 
 
 

 

找其他目录的程序并运行

 

 

绝对路径:

动态添加环境变量,才能import

原文地址:https://www.cnblogs.com/yangever/p/5769677.html