python3进阶教程_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实用库,尽情期待吧,如果觉得写得比较有条理,点波关注哟。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值