很多序列都可以實現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]