首页 > 代码库 > Python基础(二)

Python基础(二)

?成器

1. 什么是?成器

通过列表?成式,我们可以直接创建?个列表。但是,受到内存限制,列表 容量肯定是有限的。?且,创建?个包含100万个元素的列表,不仅占?很 ?的存储空间,如果我们仅仅需要访问前??个元素,那后?绝?多数元素 占?的空间都??浪费了。所以,如果列表元素可以按照某种算法推算出 来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就不必 创建完整的list,从?节省?量的空间。在Python中,这种?边循环?边计算 的机制,称为?成器:generator。

2. 创建?成器?法1

要创建?个?成器,有很多种?法。第?种?法很简单,只要把?个列表? 成式的 [ ] 改成 ( )

输入:L=[ x*2 for x in range(5)]
输出:print(L)
结果:[0, 2, 4, 6, 8]


输入:G=(x *2 for x in range(5))
输出:print (G)
结果:<generator object <genexpr> at 0x03490EA0>

创建 L 和 G 的区别仅在于最外层的 [ ] 和 ( ) , L 是?个列表,? G 是?个 ?成器。我们可以直接打印出L的每?个元素,但我们怎么打印出G的每?个 元素呢?如果要?个?个打印出来,可以通过 next() 函数获得?成器的下? 个返回值:

G=(x *2 for x in range(5))
print(next(G))
print(next(G))
print(next(G))
0
2
4
G=(x *2 for x in range(5))
for i in G:
    print(i)
0
2
4
6
8

?成器保存的是算法,每次调? next(G) ,就计算出 G 的下?个元素的值, 直到计算到最后?个元素,没有更多的元素时,抛出 StopIteration 的异常。 当然,这种不断调? next() 实在是太变态了,正确的?法是使? for 循环, 因为?成器也是可迭代对象。所以,我们创建了?个?成器后,基本上永远 不会调? next() ,?是通过 for 循环来迭代它,并且不需要关? StopIteration 异常。

总结

?成器是这样?个函数,它记住上?次返回时在函数体中的位置。对?成器 函数的第?次(或第 n 次)调?跳转?该函数中间,?上次调?的所有局部 变量都保持不变。
?成器不仅“记住”了它数据状态;?成器还“记住”了它在流控制构造(在命令 式编程中,这种构造不只是数据值)中的位置。
?成器的特点:
1. 节约内存

2. 迭代到下?次的调?时,所使?的参数都是第?次所保留下的,即是 说,在整个所有函数调?的参数都是第?次所调?时保留的,?不是新 创建的

 

迭代器

迭代是访问集合元素的?种?式。迭代器是?个可以记住遍历的位置的对 象。迭代器对象从集合的第?个元素开始访问,直到所有的元素被访问完结 束。迭代器只能往前不会后退。

1. 可迭代对象

以直接作?于 for 循环的数据类型有以下?种:
?类是集合数据类型,如 list 、 tuple 、 dict 、 set 、 str 等;
?类是 generator ,包括?成器和带 yield 的generator function。
这些可以直接作?于 for 循环的对象统称为可迭代对象: Iterable 。

 

2. 判断是否可以迭代

可以使? isinstance() 判断?个对象是否是 Iterable 对象:

 

总结

凡是可作?于 for 循环的对象都是 Iterable 类型;

凡是可作?于 next() 函数的对象都是 Iterator 类型

集合数据类型如 list dict str 等是 Iterable 但不是 Iterator ,不过可 以通过 iter() 函数获得?个 Iterator 对象。

 

装饰器

装饰器是程序开发中经常会?到的?个功能,?好了装饰器,开发效率如? 添翼,所以这也是Python?试中必问的问题,但对于好多初次接触这个知识 的?来讲,这个功能有点绕,?学时直接绕过去了,然后?试问到了就挂 了,因为装饰器是程序开发的基础知识,这个都不会,别跟?家说你会 Python, 看了下?的?章,保证你学会装饰器。

 

初创公司有N个业务部?,1个基础平台部?,基础平台负责提供底层的功 能,如:数据库操作、redis调?、监控API等功能。业务部?使?基础功能 时,只需调?基础平台提供的功能即可。如下:

def    f1():                
    print(f1)
def    f2():                
    print(f2)
def    f3():                
    print(f3)
def    f4():                
    print(f4)
###############    业务部?A    调?基础平台提供的功能    ###############
f1()
f2() 
f3()
f4()
###############    业务部?B    调?基础平台提供的功能    ###############
f1() f2() f3() f4()

 

?前公司有条不紊的进?着,但是,以前基础平台的开发?员在写代码时候 没有关注验证相关的问题,

即:基础平台的提供的功能可以被任何?使?。 现在需要对基础平台的所有功能进?重构,为平台提供的所有功能添加验证 机制,即:执?功能前,先进?验证。

??把?作交给 Low B,他是这么做的:

跟每个业务部?交涉,每个业务部???写代码,调?基础平台的功能 之前先验证。诶,这样?来基础平台就不需要做任何修改了。太棒了, 有充?的时间泡妹?...

当天Low B 被开除了…

??把?作交给 Low BB,他是这么做的:

############### 基础平台提供的功能如下 ###############
def
f1(): # 验证1 # 验证2 # 验证3 print (f1) def f2(): # 验证1 # 验证2 # 验证3 print (f2) def f3(): # 验证1 # 验证2 # 验证3 print (f3) def f4(): # 验证1 # 验证2 # 验证3 print (f4)

############### 业务部?不变 ############### ### 业务部?A 调?基础平台提供的功能###

过了?周 Low BB 被开除了…

??把?作交给 Low BBB,他是这么做的:

只对基础平台的代码进?重构,其他业务部??需做任何修改
###############    基础平台提供的功能如下    ###############    
def    check_login():               
   # 验证1
   # 验证2
   # 验证3
     pass
def f1(): check_login() print(f1) def f2(): check_login() print(f2) def f3(): check_login() print(f3) def f4(): check_login() print(f4)

 

??看了下Low BBB 的实现,嘴?漏出了?丝的欣慰的笑,语重??的跟 Low BBB聊了个天:

??说:

写代码要遵循 开放封闭 原则,虽然在这个原则是?的?向对象开发,但是也 适?于函数式编程,简单来说,它规定已经实现的功能代码不允许被修改, 但可以被扩展,即:

封闭:已实现的功能代码块

开放:对扩展开发

如果将开放封闭原则应?在上述需求中,那么就不允许在函数 f1 、f2、f3、 f4的内部进?修改代码,?板就给了Low BBB?个实现?案:

def w1(func):
    def    inner():
    # 验证1
    # 验证2
    # 验证3
    func()
    return inner

@w1
def f1():
    print (f1)
@w1
def f2():
    print (f2)
@w1
def f3():
    print (f3)
@w1
def f4():
    print (f4)

 

对于上述代码,也是仅仅对基础平台的代码进?修改,就可以实现在其他? 调?函数 f1 f2 f3 f4 之前都进?【验证】操作,并且其他业务部??需做任 何操作。
Low BBB?惊胆战的问了下,这段代码的内部执?原理是什么呢?
??正要??,突然Low BBB的?机掉到地上,恰巧屏保就是Low BBB的? 友照?,???看?紧?抖,喜笑颜开,决定和Low BBB交个好朋友。
详细的开始讲解了:
单独以f1为例:

def    w1(func):                
    def    inner():                                
        #验证1                                
        #验证2                                
        #验证3                                
    func()                
    return    inner
@w1 
def    f1():                
    print(f1)

python解释器就会从上到下解释代码,步骤如下:
1. def w1(func): ==>将w1函数加载到内存
2. @w1
没错,从表?上看解释器仅仅会解释这两句代码,因为函数在 没有被调?之 前其内部代码不会被执?。

从表?上看解释器着实会执?这两句,但是 @w1这?句代码?却有??章,@函数名是python的?种语法糖。

上例@w1内部会执??下操作:
执?w1函数 
执?w1函数,并将@w1下?的函数作为w1函数的参数,即:@w1 等价于w1(f1)所以,内部就会去执?:
def inner(): #验证 1 # #验证 2 # #验证 3 f1()    #func是参数,此时func等于f1 return inner #返回的inner,inner代表的是函数,?执?函数,其实就是将原来的f1函数塞进另外?个函数中 w1的返回值 将执?完的w1函数返回值赋值给@w1下?的函数的函数名f1即将w1 的返回值再重新赋值给f1,即: 新f1 = def inner():
  # 验证 1   # #验证 2   # #验证 3   原来f1()   return inner 所以,以后业务部?想要执?f1函数时,就会执?新f1函数,在新f1 函数内部先执?验证,再执?原来的f1函数,然后将原来f1 函数的返回 值返回给了业务调?者。 如此?来,即执?了验证的功能,?执?了原来f1函数的内容,并将原f1函 数返回值返回给业务调?着 LowBBB 你明?了吗?要是没明?的话,我晚上去你家帮你解决吧!!!

3. 再议装饰器

#定义函数:完成包裹数据 
def    makeBold(fn):                
    def    wrapped():                                
        return    "<b>"    +    fn()    +    "</b>"                
    return    wrapped
#定义函数:完成包裹数据 
def    makeItalic(fn):                
    def    wrapped():                                
        return    "<i>"    +    fn()    +    "</i>"                
    return    wrapped
@makeBold 
def    test1():                
    return    "hello world-1"
@makeItalic 
def    test2():                
    return    "hello world-2"
@makeBold 
@makeItalic
def    test3():                
    return    "hello world-3"
print(test1())) 
print(test2())) 
print(test3()))
运?结果:
<b>hello world-1</b> 
<i>hello world-2</i> 
<b><i>hello    world-3</i></b>

4. 装饰器(decorator)功能

1. 引??志

2. 函数执?时间统计

3. 执?函数前预备处理

4. 执?函数后清理功能

5. 权限校验等场景

6. 缓存

 

5. 装饰器示例

例1:?参数的函数

from    time import ctime, sleep


def timefun(func):
    def wrappedfunc():
        print ("%s    called    at    %s" % (func.__name__, ctime ()))
        func ()

    return wrappedfunc


@timefun
def foo():
    print ("I    am    foo")


foo ()
sleep (2)
foo ()
上面代码理解装饰器执行行为可理解成
foo = timefun(foo)
#foo先作为参数赋值给func后,foo接收指向timefun返回的wrappedfuncfoo()
#调?foo(),即等价调?wrappedfunc() #内部函数wrappedfunc被引?,所以外部函数的func变量(?由变量)并没有释放
#func?保存的是原foo函数对象

 

Python基础(二)