码迷,mamicode.com
首页 > 编程语言 > 详细

Day4 - Python基础4 迭代器、装饰器、软件开发规范

时间:2018-05-03 19:44:11      阅读:169      评论:0      收藏:0      [点我收藏+]

标签:规范   背景   rip   hello   ati   isp   target   stop   执行文件   

Day4 - Python基础4 迭代器、装饰器、软件开发规范

1.迭代器&生成器

 生成器

 背景:通过列表生成式能生成一个列表,但受内存限制,列表的容量肯定是有限的。而且当列表元素很多时,会占用大量内存空间,如果只是使用其中的一些元素,那其它元素会造成空间浪费

 定义:基于以上原因,如果能通过算法推导出列表的元素,这样就不需要创建完整的list,可以节省空间。这种一边循环一边计算的机制,就叫生成器。

   格式:只需把列表生成式[]改成()即可

   方法:使用next()可以获取下一个元素,不过一般用for循环打印

 函数生成器:在函数中加入yield,函数就变成了一个生成器;而且还可以利用此特性,实现协程的效果

  

 1 #普通列表
 2 list_normal = [0,1,2,3,4,5,6,7,8,9,10]  #手动生成列表
 3 print(list_normal)
 4 #列表生成式
 5 list_auto = [i for i in range(11)]  #利用算法生成列表
 6 print(list_auto)
 7 
 8 #生成器
 9 list_generator = (i for i in range(11)) #把生成式[]改成()就是生成器了
10 print(list_generator)
11 #生成器方法
12 print(next(list_generator))
13 print(next(list_generator))
14 for i in list_generator:
15     print(i)
技术分享图片
 1 #函数生成器
 2 def num_generator(num):
 3     i = 0
 4     while i <num:
 5         #print(i)
 6         yield i
 7         i +=1
 8     return done
 9 
10 nums = num_generator(5)
11 print(nums)
12 print(nums.__next__())
13 print(nums.__next__())
14 print("干点其它事")
15 print(nums.__next__())
16 print(nums.__next__())
17 print(nums.__next__())
18 #函数生成器异常捕获处理
19 while True:
20     try:
21         print("nums:",next(nums))
22     except StopIteration as e:
23         print("nums gererator return value:",e.value)
24         break
函数生成器
技术分享图片
 1 #单线程实现并发运算
 2 import time,os
 3 
 4 def command():
 5     print("开始ping啦")
 6     while True:
 7         addr = yield
 8         os.system("ping "+ + addr)
 9 
10 def ips():
11     t = command()
12     t.__next__()
13     print("开始分配IP地址")
14     for i in range(2):
15         if i == 0:
16             continue
17         else:
18             address = "10.172.116.%s"%i
19             time.sleep(1)
20             t.send(address)
21 ips()
单线程实现并发运算  

 迭代器

  可迭代对象Iterable:

  可以被for循环的数据类型,包含二类:

  1.集合数据类型:list、dict、tuple、set、str等

  2.generator,包含生成器、带yield的generator function  

1 from collections import Iterable
2 from collections import Iterator
3 
4 #判断是否是可迭代对象
5 isinstance([],Iterable)
6 isinstance({},Iterable)
7 isinstance((),Iterable)
8 isinstance(string,Iterable)
9 isinstance(100,Iterable)    #数字不可迭代

 迭代器Iterator:

  定义:可以被next()函数调用并不断返回下一个值的对象称为迭代器

  特性:

    把Iterable变成Iterator可以使用Iter()函数

    生成器都是Iterator对象,但list、tuple、dict等虽是Iterable,却不是Iterator

 1 #判断是否是迭代器
 2 isinstance([],Iterator)
 3 isinstance({},Iterator)
 4 isinstance((),Iterator)
 5 isinstance(string,Iterator)
 6 isinstance(100,Iterator)
 7 isinstance((x for x in range(10)),Iterator)
 8 
 9 #迭代对象转换成迭代器方法
10 Iter_list = iter([1,2,3])
11 print(iter_list)

 区别:

      Iterator对象表示的是一个数据流,可以被next()函数调用并不断返回下一个数据,直到数据抛出StopIteration错误。可以把Iterator看成是一个有序序列,但我们却不能提前知道序列长度,它可以表示一个无限大的数据流,如自然数,而这是list办不到的。 

 for循环本质上是通过不断调用next()实现的

技术分享图片
 1 #for循环
 2 for i in [1,2,3]:
 3     print(i)
 4 
 5 #等同于下面的迭代器
 6 a = iter([1,2,3])
 7 while True:
 8     try:
 9         next(a)
10     except StopIteration:
11         break
View Code

2.装饰器

  python装饰器:http://blog.51cto.com/egon09/1836763

  定义:本质是函数,功能是装饰其它函数,就是为其它函数添加附加功能

  原则:1.不能修改被装饰的函数的源代码(对被装饰函数是透明的)

     2.不能修改被装饰的函数的调用方式

 实现装饰器知识储备:(高阶函数+嵌套函数=装饰器)

    1.函数即“变量”

     技术分享图片

 

    2.高阶函数

     a.把一个函数名当做实参传给另一个函数(在不修改被装饰函数源代码的情况下为其添加功能)

     b.返回值中包含函数名(不修改函数的调用方式)

技术分享图片
 1 #高阶函数
 2 def bar():
 3      time.sleep(3)
 4      print(in the bar)
 5 
 6 def test2(func):
 7     print(func)
 8     return func
 9 
10 t = test2(bar)
11 t() #run bar
12 
13 bar=test2(bar)  #把之前函数bar名称覆盖了
14 bar()
高阶函数

 

    3.嵌套函数

     定义:一个函数体内用def去声明一个新的函数

技术分享图片
1 #嵌套函数
2 def foo():
3     print(in the foo)
4     def bar():
5         print(in the bar)
6     bar()
7 foo()
嵌套函数
技术分享图片
 1 #局部作用域和全局作用域的访问顺序
 2 x=0
 3 def grandpa():
 4     x=1
 5     def dad():
 6         x=2
 7         def son():
 8             x=3
 9             print(x)
10         son()
11     dad()
12 grandpa()   #结果是3,从最里面找变量
局部作用域和全局作用域的访问顺序

    4.装饰器案例

技术分享图片
 1 #装饰器案例1
 2 #运行test1-->等同于运行deco-->运行deco过程中会运行原来的test1函数-->并附加了计时功能
 3 def timer(func):    #嵌套函数 timer(test1) func=test1
 4     def deco():     #高阶函数
 5         start_time = time.time()
 6         func()      #run test1
 7         stop_time = time.time()
 8         print("run time :%s"%(stop_time-start_time))
 9     return deco     #返回deco的内存地址
10 
11 @timer  #等同于test1 = timer(test1)
12 def test1():
13     time.sleep(3)
14     print(in the test1)
15 
16 test1() #run deco
装饰器案例1
技术分享图片
 1  1 #装饰器案例2
 2  2 #实现不定量传参,装饰器更有扩展性
 3  3 def timer(func):    #嵌套函数 timer(test1) func=test1
 4  4     def deco(*arg,**kwargs):     #高阶函数
 5  5         start_time = time.time()
 6  6         func(*arg,**kwargs)      #run test1
 7  7         stop_time = time.time()
 8  8         print("run time :%s"%(stop_time-start_time))
 9  9     return deco     #返回deco的内存地址
10 10 
11 11 @timer  #等同于test1 = timer(test1)
12 12 def test1():
13 13     time.sleep(3)
14 14     print(in the test1)
15 15 
16 16 @timer  #等同于test2 = timer(test2)=deco test2(name)=deco(name)
17 17 def test2(name):
18 18     print(test2:,name)
19 19 
20 20 test1() #run deco
21 21 test2(sam)
装饰器案例2-传参
技术分享图片
 1 #网站认证装饰器-初版
 2 #需求:登录index页面不需要认证,登录home/bbs要认证(使用装饰器)
 3 user,passwd = sam,123
 4 def auth(func):    #装饰器
 5     def wrapper():
 6         username = input("Username:").strip()
 7         password = input("Password:").strip()
 8         if username == user and password == passwd:
 9             print("登录成功!")
10             func()
11         else:
12             print("用户名或密码错误.")
13     return wrapper
14 
15 def index():    #不认证
16     print("Welcome to the index page.")
17 
18 @auth
19 def home():    #装饰器认证
20     print("Welcome to the home page.")
21 
22 @auth
23 def bbs():     #装饰器认证
24     print("Welcome to the bbs page.")
25 
26 home()
27 bbs()
网站认证装饰器-初版
技术分享图片
 1 #网站认证装饰器-进阶版
 2 #需求:登录index页面不需要认证,登录home/bbs要使用认证方式(使用装饰器),home传参数且有返回值
 3 user,passwd = sam,123
 4 def auth(func):
 5     def wrapper(*args,**kwargs):
 6         username = input("Username:").strip()
 7         password = input("Password:").strip()
 8         if username == user and password == passwd:
 9             print("登录成功!")
10             res = func(*args,**kwargs)
11             #print("---认证之后---")
12             return res
13         else:
14             print("用户名或密码错误.")
15     return wrapper
16 
17 def index():
18     print("Welcome to the index page.")
19 
20 @auth
21 def home(*args):
22     print("Welcome to the home page.",args)
23     return "From home page"
24 
25 @auth
26 def bbs():
27     print("Welcome to the bbs page.")
28 
29 #home()
30 print(home(sam))
网站认证装饰器-进阶版
技术分享图片
 1 #网站认证装饰器-终极版
 2 #需求:登录index页面不需要认证,登录home/bbs要使用不同的认证方式local/ldap(使用装饰器),home传参数且有返回值
 3 user,passwd = sam,123
 4 def auth(auth_type):
 5     #print("auth func:",auth_type)
 6     def outer_wrapper(func):
 7         def wrapper(*args,**kwargs):
 8             #print("wrapper func args:", *args, **kwargs)
 9             if auth_type == local:
10                 username = input("Username:").strip()
11                 password = input("Password:").strip()
12                 if username == user and password == passwd:
13                     print("登录成功!")
14                     res = func(*args,**kwargs)
15                     #print("---认证之后---")
16                     return res
17                 else:
18                     print("用户名或密码错误.")
19             elif auth_type == ldap:
20                 print("使用Ldap认证")
21         return wrapper
22     return outer_wrapper
23 
24 def index():
25     print("Welcome to the index page.")
26 
27 @auth(auth_type=local)    #home=auth
28 def home(*args):
29     print("Welcome to the home page.",args)
30     return "From home page"
31 
32 @auth(auth_type=ldap)
33 def bbs():
34     print("Welcome to the bbs page.")
35 
36 home()
37 bbs()
网站认证装饰器-终极版

 

3.Json & pickle 数据序列化

 xml逐渐被json取代

 Json不支持函数序列化,只能处理简单的数据类型

技术分享图片
#序列化
import json

def sayhi(name):
    print("hello,",name)

info = {
    name:alex,
    age:22,
    #‘func‘:sayhi    #不能序列化函数
}

f = open("test.text","w")
f.write( json.dumps( info) )

info[age] = 21
f.write( json.dumps( info) )

f.close()

#反序列化
import json

f = open("test.text","r")

#data = json.loads(f.read()) #data = pickle.loads(f.read())

for line in f:
    print(json.loads(line))
Json

 Json是不同开发语言都支持的交互方式,pickle是python自有的

 pickle可以序列化所有数据类型,但函数不能序列

技术分享图片
 1 #序列化
 2 import pickle
 3 
 4 def sayhi(name):
 5     print("hello,",name)
 6 
 7 info = {
 8     name:alex,
 9     age:22,
10     func:sayhi
11 }
12 
13 
14 f = open("test.text","wb")
15 
16 pickle.dump(info,f) #和f.write( pickle.dumps( info) )功能一样
17 
18 f.close()
19 
20 #反序列化
21 def sayhi(name):
22     print("hello2,",name)
23 
24 f = open("test.text","rb")
25 
26 data = pickle.load(f) #和data = pickle.loads(f.read())功能一样
27 
28 print(data["func"]("Alex"))
View Code

 注:dump一次load一次,不要dump多次

4.软件目录结构规范

 bin-执行文件

 site-packages--模组

 main-主程序

 docs-说明文档

Day4 - Python基础4 迭代器、装饰器、软件开发规范

标签:规范   背景   rip   hello   ati   isp   target   stop   执行文件   

原文地址:https://www.cnblogs.com/pynetwork/p/8980509.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!