先簡單總結近一年來的python開發:基礎知識已經在實戰中消化
(1)python中的一切皆爲對象,同樣類也是對象
在大多數編程語言中,類就是一組用來描述如何生成一個對象的代碼斷,也可以說是創建對象的模板,在python中只要你使用關鍵字class,python解釋器在執行的時候就會創建一個對象,創建完類(對象之後),你可以做:
1.你可以將它賦值給一個變量
2.你可以拷⻉它
3.你可以爲它增加屬性
4.你可以將它作爲函數參數進行傳遞
(2)動態的創建類
因爲類也是對象,你可以在運行時動態的創建它們,就像其他任何對象一樣,創建方式:1.手動創建 2.使用type創建類(type有一種完全不同的功能,動態的創建類)
(3)什麼是原類
元類就是用來創建類的“東⻄”。但是我們已經學習到了Python中的類也是對象。元類就是用來創建這些類(對象)的,元類就是類的類。type就是創建類對象的類。你可以通過檢查__class__屬性來看到這一點。Python中所有的東⻄,注意,我是指所有的東
⻄——都是對象。這包括整數、字符串、函數以及類。它們全部都是對象,
而且它們都是從一個類創建而來,這個類就是type。
(4)python是動態語言
動態編程語言是高級程序設計語言 的一個類別,在計算機科學領域已被廣泛應用。它是一類 在 運行時可以改變其結構 的語言 :例如新的函數、對象、甚至代碼可以被引進,已有的函數可以被刪除或是其他結構上的變化。動態語言目前非常具有活力。例如JavaScript便是一個動態語言,除此之外如
PHP 、 Ruby 、 Python 等也都屬於動態語言,而 C 、 C++ 等語言則不屬於動態語言。
–動態語言在運行過程中可以給對象添加屬性和方法
–動態語言在運行的過程中可以刪除屬性、方法
刪除的方法:
del 對象.屬性名
delattr(對象, “屬性名”)
相對於動態語言,靜態語言具有嚴謹性,在使用動態語言需要小心使用
(5)避免動態語言中的坑
通常需要使用__slots__:
動態語言與靜態語言的不同:
動態語言:可以在運行的過程中,修改代碼
靜態語言:編譯時已經確定好代碼,運行過程中不能修改
一般使用__slot__來限制動態語言中的實例屬性
class Xuwentao(object):
slots= (“name”, “age”)
這樣就限制類Xuwentao這個類中只有name、age的屬性,定義其他的屬性報錯,使用__slots__要注意,__slots__定義的屬性僅對當前類實例起作用,對繼承的子類是不起作用的
(6)生成器–精闢總結(就是一個算法)
通過列表生成式,我們可以直接創建一個列表。但是,受到內存限制,列表容量肯定是有限的。而且,創建一個包含100萬個元素的列表,不僅佔用很大的存儲空間,如果我們僅僅需要訪問前面幾個元素,那後面絕大多數元素佔用的空間都白白浪費了。所以,如果列表元素可以按照某種算法推算出來,那我們是否可以在循環的過程中不斷推算出後續的元素呢?這樣就不必創建完整的list,從而節省大量的空間。在Python中,這種一邊循環一邊計算的機制,稱爲生成器:generator。
也就是說生成器就是一個算法,一邊循環一邊計算的機制,稱爲生成器:generator
創建生成器的方法:
----(1)要創建一個生成器,有很多種方法。第一種方法很簡單,只要把一個列表生成式的 [ ] 改成 ( )。生成器可以通過next()函數獲得生成器的下一個返回值
生成器保存的是算法,每次調用next(G),就計算出G 的下一個元素的值,直到計算到最後一個元素,沒有更多的元素時,拋出 StopIteration 的異常。當然,這種不斷調用 next() 實在是太變態了,正確的方法是使用 for 循環,因爲生成器也是可迭代對象。所以,我們創建了一個生成器後,基本上永遠不會調用next() ,而是通過for循環來迭代它,並且不需要關StopIteration異常。
-----(2)創建生成器方法2
generator非常強大。如果推算的算法比較複雜,用類似列表生成式的for循環無法實現的時候,還可以用函數來實現,會使用到關鍵字yield。
調用生成器:
g.next()
g.send()
執行到yield時,gen函數作用暫時保存,返回i的值;temp接收下次
c.send(“python”),send發送過來的值,c.next()等價c.send(None)
def gen():
i = 0
while i<5:
temp = yield i
print(temp)
i+=1
yield i 和temp=yield i的執行是一樣的:都是返回i的值
使用next:
In [11]: f = gen()
In [12]: next(f)
Out[12]: 0
In [13]: next(f)
None
Out[13]: 1
In [14]: next(f)
None
Out[14]: 2
In [15]: next(f)
None
Out[15]: 3
In [16]: next(f)
None
Out[16]: 4
In [17]: next(f)
None
-------------------------------------------------------------------------
StopIteration Traceback (most recent call las
<ipython-input-17-468f0afdf1b9> in <module>()
----> 1 next(f)
StopIteration:
使用__next__的方法:
In [18]: f = gen()
In [19]: f.__next__()
Out[19]: 0
In [20]: f.__next__()
None
Out[20]: 1
In [21]: f.__next__()
None
Out[21]: 2
In [22]: f.__next__()
None
Out[22]: 3
In [23]: f.__next__()
None
Out[23]: 4
In [24]: f.__next__()
None
-------------------------------------------------------------------------
StopIteration Traceback (most recent call las
<ipython-input-24-39ec527346a9> in <module>()
----> 1 f.__next__()
StopIteration:
使用send:
使用send和使用next是一樣的:gen.next()-----gen.send(None),如果send中填寫東西的話,也是又返回值的
In [43]: f = gen()
In [44]: f.__next__()
Out[44]: 0
In [45]: f.send('haha')
haha
Out[45]: 1
In [46]: f.__next__()
None
Out[46]: 2
In [47]: f.send('haha')
haha
Out[47]: 3
In [48]:
這裏面的操作可以自己去嘗試嘗試,對於next,send的理解,對於異步中的代碼,往往有參數需要返回,ret = yield func(),這個時候使用gen.send(ret)—ret爲其他的代碼中返回的結果,這裏面的ret和ret=yield func()是一樣的,所以說以後使用next()還是使用send()需要看看是否有具體的返回值----往往在異步程序中使用的
(7)生成器總結:
(1)生成器是這樣一個函數,它記住上一次返回時在函數體中的位置。對生成器函數的第二次(或第 n 次)調用跳轉至該函數中間,而上次調用的所有局部變量都保持不變。
(2)生成器不僅“記住”了它數據狀態;生成器還“記住”了它在流控制構造(在命令式編程中,這種構造不只是數據值)中的位置。
生成器的優點:
(1)節約內存
(2)迭代到下一次的調用時,所使用的參數都是第一次所保留下的,即是說,在整個所有函數調用的參數都是第一次所調用時保留的,而不是新創建的。下一次調用會使用上一次的變量或者參數
生成器:一個算法,一種一邊循環一邊計算的機制,稱爲生成器:generator
生成器的優點一句話就是:節約內存,斷點調用