很多序列都可以实现for循环
-在后台,for
语句调用容器对象的iter()
方法。
该函数返回一个定义了next()
方法的迭代器对象,它一次访问容器中的一个元素。
没有后续的元素时,next()
会引发StopIteration
异常,告诉 for
循环停止迭代
- 例子
>>> s = 'abc'
>>> it = iter(s)
>>> it
<iterator object at 0x00A1DB50>
>>> next(it)
'a'
>>> next(it)
'b'
>>> next(it)
'c'
>>> next(it)
Traceback (most recent call last):
File "<stdin>", line 1, in ?
next(it)
StopIteration
作用域
- 例子
def scope_test():
def do_local():
spam = "local spam"
def do_nonlocal():
nonlocal spam
spam = "nonlocal spam"
def do_global():
global spam
spam = "global spam"
spam = "test spam"
do_local()
print("After local assignment:", spam)
do_nonlocal()
print("After nonlocal assignment:", spam)
do_global()
print("After global assignment:", spam)
scope_test()
print("In global scope:", spam)
- 解读
global 语句可以用来指明某个特定的变量位于全局作用域并且应该在那里重新绑定;
nonlocal 语句表示否定当前命名空间的作用域,寻找父函数的作用域并绑定对象。
再论新式类 旧式类
区别主要有三
- 经典类是默认没有派生自某个基类的,而新式类是默认派生自object这个基类的:
# old style
class A():pass
# new style
class A(obejct):pass
经典类在类多重继承的时候是采用从左到右深度优先原则匹配方法的
而新式类是采用C3算法(不同于广度优先)进行匹配的经典类是没有MRO和instance.mro()调用的,而新式类是有的.
C3算法的一个核心是merge.
在merge列表中,如果第一个序列mro的第一个类是出现在其它序列,并且也是第一个,或者不出现其它序列,那么这个类就会从这些序列中删除,并合到访问顺序列表中
class A(O):pass
class B(O):pass
class C(O):pass
class D(A,B):pass
class E(C,D):pass
首先需要知道 O(object)的mro(method resolution order)列表是[O,]
那么接下来是:
mro(A) = [A, O]
mro(B) = [B, O]
mro(C) = [C, O]
mro(D) = [D] + merge(mro(A), mro(B), [A, B])
= [D] + merge([A, O], [B, O], [A, B])
= [D, A] + merge([O], [B, O], [B])
= [D, A, B] + merge([O], [O])
= [D, A, B, O]
mro(E) = [E] + merge(mro(C), mro(D), [C, D])
= [E] + merge([C, O], [D, A, B, O], [C, D])
= [E, C] + merge([O], [D, A, B, O], [D])
= [E, C, D] + merge([O], [A, B, O])
= [E, C, D, A, B] + merge([O], [O])
= [E, C, D, A, B, O]