python新手經常會犯的錯誤小結,有匿名函數lambda的理解,一個元素的元組,模塊導入,參數傳遞是可變的還是不可變的,迭代器和生成器的理解 ...
1 lambda函數
函數格式是lambda keys:express 匿名函數lambda是一個表達式函數,接受keys參數,返回表達式的值。所以不用return,也沒有函數名,經常用在需要key參數的函數中,比如sorted。
2 元組(),它是以逗號辨別的,而不是小括弧。比如一個元素的元組新手經常寫成(12),其實他會被解釋成單個元素12.正確的寫法應該是(12,),在元素後面加上逗號。
3 模塊導入。比如
import random
print random.choice(range(10))
和
from random import choice
print choice(range(10))
新手會有一種誤解,第二種方法只導入了一個函數,而沒有把整個模塊導入,這是錯誤的。整個模塊其實已經被導入,只是那個函數的引用被保存了起來。所以from-import這種語法不會帶來性能上的差異,也沒有節省記憶體。
4 當你有許多module,比如幾百個,想要使用時可能會想一個一個導入太麻煩,有沒有簡便的方法?答案是有的,就是將這些模塊組織成一個package。其實就是將模塊都放在一個目錄里,然後再加一個__init__.py文件,python會將其看作為package,使用裡面的函數就可以以dotted-attribute方式來訪問。
5 參數傳遞可變對象是傳引用的,不可變對象是傳值的。那麼什麼對象是可變的,什麼是不可變的。所有python對象都有三個屬性:類型、標識符和值,如果值是可變的就是可變對象,如果值不可變就是不可變對象。像數字、字元串、元組都是不可變對象,剩下的列表、字典、類、類實例等都是可變對象。
6 迭代器的理解,是實現了迭代器協議的容器對象。自己實現一個迭代器,類中要有__iter__()方法,該方法返回一個對象。這個對象要有__next__()方法,在next方法中的適當位置返回StopIteration異常。迭代器不經常使用,所以不用太擔心。有替代方法就是生成器。
class MyIterator(object): """docstring for MyIterator""" def __init__(self, num): self.num = num def __iter__(self): return self; def __next__(self): if self.num <= 0: raise StopIteration; self.num -= 1; return self.num; for each in MyIterator(5): print(each); -> 結果 4 3 2 1 0
7 生成器。函數中只要出現了yield語句就會將其轉變成一個生成器。在遇見yield語句後會保存上下文環境,並退出函數。
註意:生成器中沒有return語句。
def fun2(num): print("start generator"); while(num>0): yield num; num -=1;
a=[each for each in fun2(5)]
print(a);
->結果 start generator [5, 4, 3, 2, 1]