第一章–python數據模型
這一章主要介紹了python的特殊函數的使用和注意事項,特殊函數即內置的以‘__’爲開頭結尾的函數
- collections.namedtuple用於構造只有少數屬性但沒有方法的對象,類似於c語言中的struct https://docs.python.org/3.8/library/collections.html#collections.namedtuple
from collections import namedtuple
Student=namedtuple('Student',['name','grader'])
stu=Student('jason',2)
print(stu)
#Student(name='jason', grader=2)
- random.choice 用於從序列中隨機選出一個元素
from random import choice
arr=[1,2,3,4,5]
choice(arr)
# a num in arr
- 原文中有一句話‘僅僅實現了 _getitem_() 方法,這一摞牌就變成可迭代的’
如果類實現了__iter__方法,那麼這個類就是可迭代iterable的
對for x in arr這類語句,如果arr沒有實現__iter__,解釋器會找arr的__getitem__方法,如果有則用__getitem__迭代對象,沒有的話報錯對象不可迭代. 參考
但是!我們用isinstance(arr,collections.Iterable)來判斷arr是否可迭代時返回false,意思就是實現了__getitem__, 沒有實現__iter__的類依然不是可迭代iterable的,儘管它能跟在in 語句後面
from collections import Iterable
class Person:
def __getitem__(self, item):
return 1
person=Person()
print(isinstance(person,Iterable)) #False
for i in person:
print(i) #repeat output 1
結論:判斷類是否可迭代只需要看它是否實現了__iter__,文中這句話我覺得翻譯得不對
-
迭代通常是隱式的,比如一個集合類型沒有實現 contains 那麼if … in …運算式就會順序做一次迭代搜索,這一點在某些場景下會影響性能,要注意避免
-
特殊方法是爲了被python解釋器調用的,而不是程序員自己調用,所以不應該寫my_object.len() 而是len(my_object) __init__除外,因爲有時候要調用父類的構造函數
-
repr__和__str
repr的目標是提供明確的信息,str的目標是提供易讀的信息,如果沒有實現str,那麼在需要用到str的地方python會用repr返回的結果
https://stackoverflow.com/questions/1436703/difference-between-str-and-repr -
所有的特殊函數集合 https://docs.python.org/3/reference/datamodel.html
-
爲什麼len不是普通方法
這個問題應該等同於爲什麼len是特殊方法,答案是對於python內置類型實例x,len(x)的速度會非常快,原因是CPython對內置類型有特殊的len實現,會直接從一個C結構體中讀取對象的長度,避免調用任何方法