Python中几个疑惑

->的作用

1
2
3
4
sync def fetch(self, url: str, keys: object, repeat: int) -> (int, object:
dosomething()
return None
#-> 就是为了告诉用户具体函数参数和参数的类型

Iterable与Iterator介绍

iterable和iterator

(1)iterable:具体应该叫做可迭代对象。他的特点其实就是我的序列的大小长度已经确定了(list,tuple,dict,string等)。他遵循可迭代的协议。

可迭代协议:

  1. iter()方法。且可迭代对象中的iter()方法返回的是一个对应的迭代器。(如list对应的迭代器就是list_iterator)

(2)iterator:具体应该叫做迭代器的对象。他的特点就是他不知道要执行多少次,所以可以理解不知道有多少个元素,每调用一次next()方法,就会往下走一步,当然是用next()方法只能往下走,不会回退。是惰性的。这样我可以存很大很大的数据,即使是整个自然数,也可以很轻松的用迭代器来表示出来。他满足的是迭代器协议。

迭代器协议:

  1. iter()方法。且方法返回的Iterator对象本身
  2. next()方法,每当next()方法被调用,返回下一个值,直到没有值可以访问,这个时候会抛出stopinteration的异常。

2.iterable与Iterator的关系

从这里可以看出Iterable继承自object, Iterator继承自Iterable。


以斐波那契数列数列为例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Fib:
def __init__(self):
self.prev = 0
self.curr = 1

def __iter__(self):
return self

def __next__(self):
value = self.curr
self.curr += self.prev
self.prev = value
return value

>>> f = Fib()
>>> list(islice(f, 0, 10))
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]

Fib既是一个可迭代对象(因为它实现了iter方法),又是一个迭代器(因为实现了next方法)。实例变量prev和curr用户维护迭代器内部的状态。每次调用next()方法的时候做两件事:
为下一次调用next()方法修改状态
为当前这次调用生成返回结果
迭代器就像一个懒加载的工厂,等到有人需要的时候才给它生成值返回,没调用的时候就处于休眠状态等待下一次调用。


生成器表达式和列表推导式

1
2
3
4
5
6
>>> g = (x*2 for x in range(10))
>>> type(g)
<type 'generator'>
>>> l = [x*2 for x in range(10)]
>>> type(l)
<type 'list'>

note:

  1. 生成器是(),列表推导式是[]
  2. 生成器表达式返回生成器对象,列表推导式返回列表兑现

yield 关键字

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Fab(object): 

def __init__(self, max):
self.max = max
self.n, self.a, self.b = 0, 0, 1

def __iter__(self):
return self

def next(self):
if self.n < self.max:
r = self.b
self.a, self.b = self.b, self.a + self.b
self.n = self.n + 1
return r
raise StopIteration()
1
2
3
4
5
6
7
8
9
10
def fab(max): 
n, a, b = 0, 0, 1
while n < max:
yield b
# print b
a, b = b, a + b
n = n + 1
t = fab(45)
for i in t:
print(i)

注意
yield x,y会返回两个迭代器(按照指针理解),这两个迭代器可以分别迭代x,y,

迭代器的具体使用方法是放在for循环中

1
2
for p(某一轮迭代中,迭代器的具体值) in 迭代器:
print(p)

一个带有 yield 的函数就是一个 generator,它和普通函数不同,生成一个 generator 看起来像函数调用,但不会执行任何函数代码,直到对其调用 next()(在 for 循环中会自动调用 next())才开始执行。

return返回的是具体的数值或者函数,而yield返回的是一个生成器对象(生成器的实例化)
可以简单理解为一个迭代器的某一部分,yield是惰性的,内存占用小,这个生成器对象每次被迭代(也就是被调用next函数时,会初始化迭代器中的指定元素,并且为下一个元素的迭代做准备工作)


python self

假如你有一个类称为MyClass和这个类的一个实例MyObject。

当你调用这个对象的方法MyObject.method(arg1, arg2)的时候,这会由Python自动转为MyClass.method(MyObject, arg1, arg2).