python进阶教程

1.迭代器
顾名思义,迭代器就是用于迭代操作(for 循环)的对象,它像列表一样可以迭代获取其中的每一个元素,任何实现了 next 方法的(对象)都可以称为迭代器。
它与列表的区别在于,构建迭代器的时候,不像列表把所有元素一次性加载到内存,而是以一种延迟计算(lazy evaluation)方式返回元素,这正是它的优点
话不多说,我们来看一个例子

class Fib(object):
     def __int__(_self,n):
           self.n = n 
           self.cur = 1
           self.prev = 0

    def __iter__(self):
          return self

    def __next__(self):
          if self.n > 0
             // python里面这种赋值超爽有木有
             self.cur,self.prev = self.cur + self.prev,self.cur 
             self.n -= 1
             return self.cur
          else:
             raise stopIteration()
f = Fib(10)
print([i for i in f])
#[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]

上面以斐波那契数列为例来实现一个迭代器:
        

Fib类实现了魔术方法,在每回迭代的时候会调用next方法
2.魔术方法
咱们由浅入深举三个例子把

class student(object):
        def __init__(self, name):
              self.name = name
        def __call__(self):
              print 'my name is {0}'.format(self.name)
aa = student('aa')
aa()  会调用call()方法  
output: 'My name is aa'

class A():
    def __init__(self):
        print "call __init__"
        self.value = [1,2,3,4,5,6]

    def __len__(self):
        print "call __len__"
        return len(self.value)

    def __getitem__(self, index):
        print "call __getitem__"
        return self.value[index]
aa = A()
print (len(aa))  ========   6
print aa[2]   ======== 3   这里调用了getItem方法  取下标为2的值

看一个稍微复杂一点的

class ListMetaclass(type):
        def __new__(cls, name, bases, attrs):
            attrs['add'] = lambda self, value: self.append(value)
            return type.__new__(cls, name, bases, attrs)
   

class MyList(list, metaclass=ListMetaclass):
           pass

ld = MyList()
ld.add('ni')
ld ========= ['ni']

这个涉及到了元类,跟js里面的原型有相似之处,但比原型好理解些。
简单解释一下:
Mylist继承了list是一个列表类,具有append方法,然后她后面又跟了个metaclass也就是元类,所有继承该元类的类都拥有add方法,是一个lambda表达式的函数self.append(value),所以知道为什么能有append了吧。
今天不深究,下回有时间我会搞一期元类和魔术方法的专题。

3.生成器
生成器算得上是Python语言中最吸引人的特性之一,生成器其实是一种特殊的迭代器,不过这种迭代器更加优雅。它不需要再像上面的类一样写iter()和next()方法了,只需要一个yiled关键字。

from itertools import islice
def fib():
    prev, curr = 0, 1
    while True:
        yield curr
        prev, curr = curr, curr + prev
 
>>> f = fib()
>>> list(islice(f, 0, 10))
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]

itertools是一个很有用的工具类,大家自行google
生成器都有一个send方法

def count(n):
    x = 0
    while x < n:
        value = yield x
        if value is not None:
            print 'Received value: %s' %value
        x += 1

gen = count(5)
print  (gen.__next__())  # print 0
print (gen.send('Hello') ) # Received value: Hello, then print 1

注意用的python3版本的要调用next方法 打印需要加括号
来一个综合一点的例子

def consumer():
    last = ''
    while True:
        //receival是生成器send过来的值
        receival = yield last
        if receival is not None:
            print ('Consume %s' % receival)
            last = receival


def producer(gen, n):
    //这一步启动生成器很关键
    gen.__next__()
    x = 0
    while x < n:
        x += 1
        print ('Produce %s' % x)
        print (gen.send(x))

    gen.close()

gen = consumer()
producer(gen, 5)
output:
Produce 1
Consume 1
1
Produce 2
Consume 2
2
...

结束循环时,用生成器的close方法关闭她。

4.装饰器
搞过java开发的人应该知道,aop面向切面织入方法。玩过angular的也应该知道,依赖注入也是装饰器的一种,很幸运2者我都接触过。

import time
def performance(f):
    @functools.wraps(decorated)
    def fn(*args, **kw):
        t1 = time.time()
        r = f(*args, **kw)
        t2 = time.time()
        print 'call %s() in %fs' % (f.__name__, (t2 - t1))
        return r
    return fn

@performance
def factorial(n):
    return reduce(lambda x,y: x*y, range(1, n+1))
print factorial(10)

说明2点,@functools.wraps(decorated)是保证factorial函数被装饰后名字不变,
另外reduce在python3中需要引入。
下面介绍一下装饰器传参的用法

import json
import functools

def json_output(indent=None, sort_keys=False):
    //想想这里为什么会多一层函数 以前的外层装饰器参数是被修饰的函数
    def actual_decorator(func):
        @functools.wraps(func)
        def inner(*args, **kwargs):
            result = func(*args, **kwargs)
            return json.dumps(result, indent=indent, sort_keys=sort_keys)

        return inner

    return actual_decorator

@json_output(18, sort_keys=True)
def f():
    return {'status': 'done','aa':'bb'}
print (f())
output:
 {
                  "aa":"bb",
                  "status":"done"
}

写到这里chrome居然崩溃了。。。
上面的意思是序列化一个json,缩进18,按键排序。
好了,今天说了iterator,generator,decrator,还有魔术方法,下回会跟大家分享爬虫或者python实用库,尽情期待吧,如果觉得写得比较有条理,点波关注哟。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,378评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,356评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,702评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,259评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,263评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,036评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,349评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,979评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,469评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,938评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,059评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,703评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,257评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,262评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,485评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,501评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,792评论 2 345

推荐阅读更多精彩内容

  • 本文为《爬着学Python》系列第十四篇文章。 中间因为工作原因隔了好久没有更新,现在稳定很多,会陆续开始更新。不...
    SyPy阅读 12,082评论 1 10
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,599评论 18 139
  • 1.1==,is的使用 ·is是比较两个引用是否指向了同一个对象(引用比较)。 ·==是比较两个对象是否相等。 1...
    TENG书阅读 724评论 0 0
  • 把函数视为对象:一等函数 把函数视为对象 python函数是对象。 高阶函数 函数式编程的特点之一是使用高阶函数。...
    plutoese阅读 1,447评论 0 52
  • 我还
    文字苏梦阅读 148评论 0 0