導航:首頁 > 編程語言 > pythontornado協程

pythontornado協程

發布時間:2023-05-27 11:26:33

① 說說這篇我為什麼從python轉向go

恩看了這篇我為什麼從python轉向go,
看來作者也是 KSO 輕辦公/企業快盤團隊的。作為快盤從無到有時期的工程師之一(總是被瀟灑哥說他們改我留下的 bug ),又恰好是
Python/Go 雙修(大霧其實我是 Rust 黨),其實一開始我是拒絕的,ang ang ang,那就隨手寫一點把。

一段段來吧,首先作者說 Python 是動態語言

python是一門動態語言,不是強類型系統。對於一個變數,我們有時候壓根不知道它是什麼類型,然後就可能出現int + string這樣的運行時錯誤。

在python裡面,可以允許同名函數的出現,後一個函數會覆蓋前一個函數,有一次我們系統一個很嚴重的錯誤就是因為這個導致的。

事實上,如果是靜態檢查,pylint 和 pyflakes 是可以做這件事的,雖然不能和 go
那種靜態編譯型語言比,但也侍枯足夠了。如果沒記錯的話,阿通當年是要求全組都在提交前做靜態檢查的。我認為這種問題更多的應該是人員素質上來避免,畢竟蔥頭
也說過,代碼自己寫的就要多回頭看看,看能不能重構,能不能做更好。不是說偷懶不行,但是從中得出 Python
動態特性太靈活,Python:怪我咯?

另外,函數作為第一對象,在 Python 中是 feature,Go 要寫個 mock,簡直虐得不要不要的。

其實這個一直是很多人吐槽python的地方,不過想想,python最開始是為了解決啥問題而被開發出來的?我們硬是要將他用到高性能伺服器開發上面,其實也是有點難為它。

如果沒記錯,無論是輕辦公還是快盤,是重 IO 不重 CPU,最大耗時是數據塊加密老尺洞那塊,我在的時候是 java 寫的。另外高性能伺服器選 Go 也是虐得不要不要的,各種小心翼翼避免 GC。大多數極端情況下,pypy 的性能足矣勝任了,我認為這不算充分條件。

python的GIL導致導致無法真正的多線程,大家可能會說我用多進程不就完了。但如果一些計算需要涉及到多進程交互,進程之間的通訊開銷也是不得不考慮的。

其實,Python 有宏可以繞開這個 GIL,但是呢架構設計得好其實可以避免的,到非同步那塊我會說。

無狀態的分布式處理使用多進程很方便,譬如處理http請求,我們就是在nginx後面掛載了200多個django server來處理http的,但這么多個進程自然導致整體機器負載偏高。

但即使我們使用了多個django進程來處理http請求,對於一些超大量請求,python仍然處理不過來。所以我們使用openresty,將高頻次的http請求使用lua來實現。可這樣又導致使用兩種開發語言,而且一些邏輯還得寫兩份不同的代碼。

如果推測沒錯,你們現在還在用五年前寫的 Gateway?那個基於 django route
的流量分發層?四年前我離開的時候已經小范圍的使用 Flask+Gevent Demo 測試過了,無論是性能還是負載都比同步模型的 django
有優勢。如果還是 django
這套的話,我只能說比較遺憾,畢竟當年金山新員工大賽頭牌就是我和幾個小夥伴寫的實時同步在線文檔編輯系統,用的就是這套技術。

因此這是個工程問題,並非語言問題。 Python 提供給了你了這么多工具,硬要選一個傳統的,Old fashion 的,Python:怪我咯?

django的網路是同步阻塞的,也就是說,如果我們需要訪問外部的一個服務,在等待結果返回這段時間,django不能處理任何其他的邏輯(當然,多線程的除外)。如果訪問外部服務需要很長時間,那就意味著我們的整個服務幾乎在很長一段時間完全不可用。

為了解決這個問題,我們只能不斷的多開django進程,同時需要保證所有服務都能快速的處理響應,但想想這其實是一件很不靠譜的事情。

同步模型並非不行,因為 overhead 足夠低,很多業務場景下用同步模型反而會取得更好的效果,比如豆瓣。同步模型最大的問題是對於 IO 密集型業務等待時間足夠長,這時候需要的不是換語言 ,而是提醒你是不是架構要改一下了。

雖然tornado是困租非同步的,但是python的mysql庫都不支持非同步,這也就意味著如果我們在tornado裡面訪問資料庫,我們仍然可能面臨因為資料庫問題造成的整個服務不可用。

tornado 是有這個問題,但是 gevent 已經解決了。我在 node.js 的某問題下曾經回答過,對於 node
而言,能選擇的非同步模型只有一個,而 Python 就是太多選擇了。另外 pypy+tornado+redis
可以隨意虐各種長連接的場景,比如我給我廠寫過的一個 push service。

其實非同步模型最大的問題在於代碼邏輯的割裂,因為是事件觸發的,所以我們都是通過callback進行相關處理,於是代碼裡面就經常出現干一件事情,傳一個callback,然後callback裡面又傳callback的情況,這樣的結果就是整個代碼邏輯非常混亂。

這個還真不是,如果說沒有 ES6 的 JavaScript,可能真有 Callback hell,但這是 Python 啊!Python
早就實現了左值綁定唉,yield 那姿勢比某些天天吹的語言不知道高到哪裡去了,當然我說的是完整版的 Python3 yield。即便是不完整的
Python 2 yield 用於非同步表達式求值也是完全足夠的,tornado 的 gen.coroutine 啊。

同步形態寫非同步,在 Python 實力強的公司裡面早普及了,這是個工程問題,並非語言問題。當然把這種事怪在 Python 身上,Python:怪我咯?

python沒有原生的協程支持,雖然可以通過gevent,greenlet這種的上patch方式來支持協程,但畢竟更改了python源碼。另外,python的yield也可以進行簡單的協程模擬,但畢竟不能跨堆棧,局限性很大,不知道3.x的版本有沒有改進。

無論是 Gevent 還是 Greenlet 均沒修改 Python 源碼,事實上這貨已經成為了 Py2 coroutine 的標准,加上豆瓣開源出來的greenify,基本上所有的庫都可以平滑的非同步化,包括 MySQL 等 C 一級的 lib。自從用上這套技術後,豆瓣的 Python dev 各種爽得不要不要的。

當我第一次使用python開發項目,我是沒成功安裝上項目需要的包的,光安裝成功mysql庫就弄了很久。後來,是一位同事將他整個python目錄打包給我用,我才能正常的將項目跑起來。話說,現在有了docker,是多麼讓人幸福的一件事情。

而部署python服務的時候,我們需要在伺服器上面安裝一堆的包,光是這一點就讓人很麻煩,雖然可以通過puppet,salt這些自動化工具解決部署問題,但相比而言,靜態編譯語言只用扔一個二進制文件,可就方便太多了。

恰好我又是在開發基於 docker 的平台, docker 還真不是用來做部署這事的。首先, Python 是有 virtualenv
這個工具的,事實上對比包管理和包隔離,Python 比 Go 高得不知道哪裡去了。Python 跟 Git 談笑風生的時候, Go 的 dev
們還得考慮我怎樣才能使得 import 的包穩定在一個版本上(當然現在有很多第三方方案)。Virtualenv + Pip 完全可以實現
Python 部署自動化,所以這個問題我認為是,工具鏈選取問題。畢竟是個十幾年的老妖怪了,Python
啥情況沒見過啊,各種打包工具任君選擇,強行說 Python 部署不方便,Python:怪我咯?

python非常靈活簡單,寫c幾十行代碼才能搞定的功能,python一行代碼沒准就能解決。但是太簡單,反而導致很多
同學無法對代碼進行深層次的思考,對整個架構進行細致的考量。來了一個需求,啪啪啪,鍵盤敲完開速實現,結果就是代碼越來越混亂,最終導致了整個項目代碼
失控。

曾經知乎有個帖子問 Python 會不會降低程序員編程能力,
我只能說這真的很人有關。你不去思考深層次的東西怪語言不行是沒道理的,那好,Go 裡面 goroutine 是怎麼實現的,一個帶 socket 的
goroutine
最小能做到多少內存,思考過?任何語言都有自己的優勢和劣勢,都需要執行者自己去判斷,一味的覺得簡單就不會深入思考這是有問題的。另外,代碼混亂我認為
還是工程上的控制力不夠,豆瓣有超過10W行的 Python 實現,雖然不說很完美,大體上做到了不會混亂這么個目標。

還有,C 寫幾十行搞定的 Python 一行解決這絕對是重大 feature,生產力啊,人員配置啊,招人培養的成本啊,從工程上來說,Python 在這一塊完全是加分項,不是每個項目都要求極致的並發,極致的效率,做工程很多時候都是要取捨的。

雖然java和php都是最好的編程語言(大家都這么爭的),但我更傾向一門更簡單的語言。而openresty,雖然性
能強悍,但lua仍然是動態語言,也會碰到前面說的動態語言一些問題。最後,前金山許式偉用的go,前快盤架構師蔥頭也用的go,所以我們很自然地選擇了
go。

Openresty 用 lua 如果按照動態語言的角度去看,還真算不上,頂多是個簡單點的 C。許式偉走的時候大多數都是
CPP,蔥頭目前我還不知道他創業用的是什麼寫的,不過他肯定沒語言傾向。當年無論是 leo 還是 ufa,一個用 Python 一個用
Java, 他都是從工程實際來選擇使用什麼樣的語言。

error,好吧,如果有語言潔癖的同學可能真的受不了go的語法,尤其是約定的最後一個返回值是error。

這其實是 Go style,無論是 go fmt 還是 error style,Go 其實是想抹平不同工程師之間的風格問題。不再為了一個縮進和大括弧位置什麼的浪費時間。這種方法並不是不好,只是我個人覺得沒 rust 那種返回值處理友善。

GC,java的GC發展20年了,go才這么點時間,gc鐵定不完善。所以我們仍然不能隨心所欲的寫代碼,不然在大請求量下面gc可能會卡頓整個服務。所以有時候,該用對象池,內存池的一定要用,雖然代碼丑了點,但好歹性能上去了。

1.4 開始 go 就是 100% 精確 GC 了,另外說到卡頓啊,完全和你怎麼用對象有關,能內聯絕不傳引用大部分場景是完全足夠的,這樣 gc 的影響程度會最低。實在想用池……只能說為啥不選 Java。

天生的並行支持,因為goroutine以及channel,用go寫分布式應用,寫並發程序異常的容易。沒有了蛋疼的callback導致的代碼邏輯割裂,代碼邏輯都是順序的。

這是有代價的,goroutine 的內存消耗計算(當然1.3還是1.4開始得到了很大的改善,內存最小值限制已經沒了),channel
跨線程帶來的性能損耗(跨線程鎖),還有對 goroutine 的控制力幾乎為 0
等。總之這種嘛,算不上是殺手級特性,大家都有,是方便了一點,但也有自己的弊端。比如我們用 go 吧,經常就比較蛋疼 spawn 出去的
goroutine 怎麼優美的 shutdown,反而有時候把事情做復雜化了。

性能,go的性能可能趕不上c,c++以及openresty,但真的也挺強悍的。在我們的項目中,現在單機就部署了一個go的進程,就完全能夠勝任以前200個python進程乾的事情,而且CPU和MEM佔用更低。

我不嚴謹的實測大概 gevent+py2 能達到同樣邏輯 go 實現的 30%~40%,pypy+tornado 能達到
80%~90%,混合了一些計算和連接處理什麼的。主要還是看業務場景吧,純粹的 CPU bound 當然是 go 好,純粹的 IO bound
你就是用 C 也沒用啊。

運維部署,直接編譯成二進制,扔到伺服器上面就成,比python需要安裝一堆的環境那是簡單的太多了。當然,如果有cgo,我們也需要將對應的動態庫給扔過去。

我們現在根據 glibc 所處的 host 版本不同有2套編譯環境,看上去是部署簡單了,編譯起來坑死你。另外雖然說 disk 便宜,這幾行代碼就幾M了,集群同步部署耗時在某些情況下還真會出簍子。

開發效率,雖然go是靜態語言,但我個人感覺開發效率真的挺高,直覺上面跟python不相上下。對於我個人來說,最好的
例子就是我用go快速開發了非常多的開源組件,譬如ledisdb,go-mysql等,而這些最開始的版本都是在很短的時間裡面完成的。對於我們項目來
說,我們也是用go在一個月就重構完成了第一個版本,並發布。

② 如何用Python一門語言通吃高性能並發,GPU計算和深度學習

第一個就是並發本身所帶來的開銷即新開處理線程、關閉處理線程、多個處理線程時間片輪轉所帶來的開銷。

實際上對於一些邏輯不那麼復雜的場景來說這些開銷甚至比真正的處理邏輯部分代碼的開銷更大。所以我們決定採用基於協程的並發方式,即服務進程只有一個(單cpu)所有的請求數據都由這個服務進程內部來維護,同時服務進程自行調度不同請求的處理順序,這樣避免了傳統多線程並發方式新建、銷毀以及系統調度處理線程的開銷。基於這樣的考慮我們選擇了基於Tornado框架實現api服務的開發。Tornado的實現非常簡潔明了,使用python的生成器作為協程,利用IOLoop實現了調度隊列。

第二個問題是資料庫的性能,這里說的資料庫包括MongoDB和Redis,我這里分開講。

先講MongoDB的問題,MongoDB主要存儲不同的用戶對於驗證的不同設置,比如該顯示什麼樣的圖片。
一開始每次驗證請求都會查詢MongoDB,當時我們的MongoDB是純內存的,同時三台機器組成一個復制集,這樣的組合大概能穩定承載八九千的qps,後來隨著我們驗證量越來越大,這個承載能力逐漸就成為了我們的瓶頸。
為了徹底搞定這個問題,我們提出了最極端的解決方案,乾脆直接把資料庫中的數據完全緩存到服務進程里定期批量更新,這樣查詢的開銷將大大降低。但是因為我們用的是Python,由於GIL的存在,在8核伺服器上會fork出來8個服務進程,進程之間不像線程那麼方便,所以我們基於mmap自己寫了一套夥伴演算法構建了一個跨進程共享緩存。自從這套緩存上線之後,Mongodb的負載幾乎變成了零。
說完了MongoDB再說Redis的問題,Redis代碼簡潔、數據結構豐富、性能強大,唯一的問題是作為一個單進程程序,終究性能是有上限的。
雖然今年Redis發布了官方的集群版本,但是經過我們的測試,認為這套分布式方案的故障恢復時間不夠優秀並且運維成本較高。在Redis官方集群方案面世之前,開源世界有不少proxy方案,比如Twtter的TwemProxy和豌豆莢的Codis。這兩種方案測試完之後給我們的感覺TwemProxy運維還是比較麻煩,Codis使用起來讓人非常心曠神怡,無論是修改配置還是擴容都可以在配置頁面上完成,並且性能也還算不錯,但無奈當時Codis還有比較嚴重的BUG只能放棄之。
幾乎嘗試過各種方案之後,我們還是下決心自己實現一套分布式方案,目的是高度貼合我們的需求並且運維成本要低、擴容要方便、故障切換要快最重要的是數據冗餘一定要做好。
基於上面的考慮,我們確定基於客戶端的分布式方案,通過zookeeper來同步狀態保證高可用。具體來說,我們修改Redis源碼,使其向zookeeper注冊,客戶端由zookeeper上獲取Redis伺服器集群信息並根據統一的一致性哈希演算法來計算數據應該存儲在哪台Redis上,並在哈希環的下一台Redis上寫入一份冗餘數據,當讀取原始數據失敗時可以立即嘗試讀取冗餘數據而不會造成服務中斷。

③ python容易學么

Python相比於其他編程語言更容易學習,但是想學精通還是需要選擇好的教程和好的師傅的,給你個課程大綱,你對比一下,很全面的!
階段一:Python開發基礎隱頌肆
Python全棧開發與人工智慧之Python開發基礎知識學習內容包括:Python基礎語法、數據櫻笑類型、字元編碼、文件操作、函數、裝飾器、迭代器、內置方法、常用模塊等。
階段二:Python高級編程和資料庫開發
Python全棧開發與人工智慧之Python高級編程和資料庫開發知識學習內容包括:面向對象開發、Socket網路編程、線程、進程、隊列、IO多路模型、Mysql資料庫開發等。
階段三:前端開發
Python全棧開發與人工智慧之前端開發知識學習內容包括:Html、CSS、JavaScript開發、灶轎Jquery&bootstrap開發、前端框架VUE開發等。
階段四:WEB框架開發
Python全棧開發與人工智慧之WEB框架開發學習內容包括:Django框架基礎、Django框架進階、BBS+Blog實戰項目開發、緩存和隊列中間件、Flask框架學習、Tornado框架學習、Restful API等。
階段五:爬蟲開發
Python全棧開發與人工智慧之爬蟲開發學習內容包括:爬蟲開發實戰。
階段六:全棧項目實戰
Python全棧開發與人工智慧之全棧項目實戰學習內容包括:企業應用工具學習、CRM客戶關系管理系統開發、路飛學城在線教育平台開發等。
階段七:數據分析
Python全棧開發與人工智慧之數據分析學習內容包括:金融量化分析。
階段八:人工智慧
Python全棧開發與人工智慧之人工智慧學習內容包括:機器學習、數據分析 、圖像識別、自然語言翻譯等。
階段九:自動化運維&開發
Python全棧開發與人工智慧之自動化運維&開發學習內容包括:CMDB資產管理系統開發、IT審計+主機管理系統開發、分布式主機監控系統開發等。
階段十:高並發語言GO開發
Python全棧開發與人工智慧之高並發語言GO開發學習內容包括:GO語言基礎、數據類型與文件IO操作、函數和面向對象、並發編程等。

④ tornado 怎麼利用'next'參數進行頁面跳轉

本質上什麼是協程?舉個例子:就是類似goto一樣
可以在多個fun之間來回跳轉~
比輪晌如A函數執行到一半然後switch到B函數執行~~諸如此類.
那如果只考慮一個函數呢??那對於A函數而言:其實就是其可以執行到一半先停下,干點別的事情後再接著往下運行~
看到這里你是不是想到了debug時的打斷點??執行到斷點的時候就停下,只有next往下setp時候這個函數才接著往下執行~對不對?
那如果我們可以實現類似的斷點機制,是不是就可以實現多個函數來回跳轉呢?A函數執行到斷點時就停下,系統去B執行~等B執行完畢了才回來接著step往斷點後邊的代碼航執行~~~~協程其實就是這么個東西,那麼在Python中山門可以實現debug斷點功能呢?當然是yield了~~執行到中間的yield系統就停下返回了~之後在調用next時才回接著往下執行~~~
你看,是不是通過這個東西就可以做到多芹桐純個函數之間來回跳轉??!恩,那山門時候跳轉呢?之前是yield才會,那我是不是可以將之封裝一下呢?封裝成:一個協程,然後sleep就yield出來~~
折下來就做到協程的功能來~~嫌咐本質上就是這么回事~~~別聽別人說的多懸乎~~~只是在這個基礎模型上又加了很多manager的功能等等~~

⑤ python非同步有哪些方式

yield相當於return,他將相應的值返回給調用next()或者send()的調用者,從而交出了CPU使用權,而當調用者再次調用next()或者send()的時候,又會返回到yield中斷的地方,如果send有參數,還會將參數返回給yield賦值的變數,如果沒有就和next()一樣賦值為None。但是這里會遇到一個問題,就是嵌套使用generator時外層的generator需要寫大量代碼,看如下示例:
注意以下代碼均在Python3.6上運行調試

#!/usr/bin/env python# encoding:utf-8def inner_generator():
i = 0
while True:
i = yield i if i > 10: raise StopIterationdef outer_generator():
print("do something before yield")
from_inner = 0
from_outer = 1
g = inner_generator()
g.send(None) while 1: try:
from_inner = g.send(from_outer)
from_outer = yield from_inner except StopIteration: breakdef main():
g = outer_generator()
g.send(None)
i = 0
while 1: try:
i = g.send(i + 1)
print(i) except StopIteration: breakif __name__ == '__main__':
main()041

為了簡化,在Python3.3中引入了yield from

yield from

使用yield from有兩個好處,

1、可以將main中send的參數一直返回給最里層的generator,
2、同時我們也不需要再使用while循環和send (), next()來進行迭代。

我們可以將上邊的代碼修改如下:

def inner_generator():
i = 0
while True:
i = yield i if i > 10: raise StopIterationdef outer_generator():
print("do something before coroutine start") yield from inner_generator()def main():
g = outer_generator()
g.send(None)
i = 0
while 1: try:
i = g.send(i + 1)
print(i) except StopIteration: breakif __name__ == '__main__':
main()

執行結果如下:

do something before coroutine start123456789101234567891011

這里inner_generator()中執行的代碼片段我們實際就可以認為是協程,所以總的來說邏輯圖如下:

我們都知道Python由於GIL(Global Interpreter Lock)原因,其線程效率並不高,並且在*nix系統中,創建線程的開銷並不比進程小,因此在並發操作時,多線程的效率還是受到了很大制約的。所以後來人們發現通過yield來中斷代碼片段的執行,同時交出了cpu的使用權,於是協程的概念產生了。在Python3.4正式引入了協程的概念,代碼示例如下:

import asyncio# Borrowed from http://curio.readthedocs.org/en/latest/[email protected] countdown(number, n):
while n > 0:
print('T-minus', n, '({})'.format(number)) yield from asyncio.sleep(1)
n -= 1loop = asyncio.get_event_loop()
tasks = [
asyncio.ensure_future(countdown("A", 2)),
asyncio.ensure_future(countdown("B", 3))]
loop.run_until_complete(asyncio.wait(tasks))
loop.close()12345678910111213141516

示例顯示了在Python3.4引入兩個重要概念協程和事件循環,
通過修飾符@asyncio.coroutine定義了一個協程,而通過event loop來執行tasks中所有的協程任務。之後在Python3.5引入了新的async & await語法,從而有了原生協程的概念。

async & await

在Python3.5中,引入了aync&await 語法結構,通過」aync def」可以定義一個協程代碼片段,作用類似於Python3.4中的@asyncio.coroutine修飾符,而await則相當於」yield from」。

先來看一段代碼,這個是我剛開始使用async&await語法時,寫的一段小程序。

#!/usr/bin/env python# encoding:utf-8import asyncioimport requestsimport time


async def wait_download(url):
response = await requets.get(url)
print("get {} response complete.".format(url))


async def main():
start = time.time()
await asyncio.wait([
wait_download("http://www.163.com"),
wait_download("http://www.mi.com"),
wait_download("http://www.google.com")])
end = time.time()
print("Complete in {} seconds".format(end - start))


loop = asyncio.get_event_loop()
loop.run_until_complete(main())

這里會收到這樣的報錯:

Task exception was never retrieved
future: <Task finished coro=<wait_download() done, defined at asynctest.py:9> exception=TypeError("object Response can't be used in 'await' expression",)>
Traceback (most recent call last):
File "asynctest.py", line 10, in wait_download
data = await requests.get(url)
TypeError: object Response can't be used in 'await' expression123456

這是由於requests.get()函數返回的Response對象不能用於await表達式,可是如果不能用於await,還怎麼樣來實現非同步呢?
原來Python的await表達式是類似於」yield from」的東西,但是await會去做參數檢查,它要求await表達式中的對象必須是awaitable的,那啥是awaitable呢? awaitable對象必須滿足如下條件中其中之一:

1、A native coroutine object returned from a native coroutine function .

原生協程對象

2、A generator-based coroutine object returned from a function decorated with types.coroutine() .

types.coroutine()修飾的基於生成器的協程對象,注意不是Python3.4中asyncio.coroutine

3、An object with an await method returning an iterator.

實現了await method,並在其中返回了iterator的對象

根據這些條件定義,我們可以修改代碼如下:

#!/usr/bin/env python# encoding:utf-8import asyncioimport requestsimport time


async def download(url): # 通過async def定義的函數是原生的協程對象
response = requests.get(url)
print(response.text)


async def wait_download(url):
await download(url) # 這里download(url)就是一個原生的協程對象
print("get {} data complete.".format(url))


async def main():
start = time.time()
await asyncio.wait([
wait_download("http://www.163.com"),
wait_download("http://www.mi.com"),
wait_download("http://www.google.com")])
end = time.time()
print("Complete in {} seconds".format(end - start))


loop = asyncio.get_event_loop()
loop.run_until_complete(main())27282930

好了現在一個真正的實現了非同步編程的小程序終於誕生了。
而目前更牛逼的非同步是使用uvloop或者pyuv,這兩個最新的Python庫都是libuv實現的,可以提供更加高效的event loop。

uvloop和pyuv

pyuv實現了Python2.x和3.x,但是該項目在github上已經許久沒有更新了,不知道是否還有人在維護。
uvloop只實現了3.x, 但是該項目在github上始終活躍。

它們的使用也非常簡單,以uvloop為例,只需要添加以下代碼就可以了

import asyncioimport uvloop
asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())123

⑥ 零基礎學Python,是自學好還是報培訓班好

學電腦不如學【視頻剪輯】,理由很簡單,容易學(不像其它行業學習成本高,難度大),適合短期3-4個月短期學習,而且行業缺口非常大,無論是找工作還是自己在家裡接私單,月收入輕松過萬,兩三萬也是稀鬆平常。【點擊進入】免費「短視頻剪輯後期」學習網址:
www.huixueba.net/web/AppWebClient/AllCourseAndResourcePage?type=1&tagid=313&zdhhr-11y17r-141187050229786925

因為現在【短視頻】的崛起,任何企業,任何工作室或者個人都需要製作剪輯大量的短視頻來包裝品牌,發抖音,發朋友圈,發淘寶等自媒體渠道做展示。因為每天都要更新並發布新內容,所以剪輯師根本招不夠,,供需失衡就造成了剪輯師高薪水。

而且剪輯這個技術並不需要高超的電腦技術,也不需要美術音樂造詣,基本都是固定套路,要什麼風格的片要什麼節奏,經過三四個月的培訓都可以輕松掌握。但凡有點電腦基礎會用滑鼠拖拽,會點擊圖標,會保存除非自己不想學,沒有學不會的。但是要學好學精,就一定要找專業負責的培訓機構了,推薦這個領域的老大:王氏教育。

在「短視頻剪輯/短視頻運營/視頻特效」處理這塊,【王氏教育】是國內的老大,每個城市都是總部直營校區。跟很多其它同類型大機構不一樣的是:王氏教育每個校區都是實體面授,老師是手把手教,而且有專門的班主任從早盯到晚,爆肝式的學習模式,提升會很快,特別適合0基礎的學生。王氏教育全國直營校區面授課程試聽【復制後面鏈接在瀏覽器也可打開】: www.huixueba.com.cn/school/yingshi?type=2&zdhhr-11y17r-141187050229786925


大家可以先把【繪學霸】APP下載到自己手機,方便碎片時間學習——繪學霸APP下載: www.huixueba.com.cn/Scripts/download.html

⑦ Python都需要那些技術

分享Python學習路線。
第一階段Python基礎與Linux資料庫。這是Python的入門階段,也是幫助零基礎學員打好基礎的重要階段。你需要掌握Python基本語法規則及變數、邏輯控制、內置數據結構、文件操作、高級函數、模塊、常用標准庫模塊、函數、異常處理、MySQL使用、協程等知識點。
學習目標:掌握Python基礎語法,具備基礎的編程能力;掌握Linux基本操作命段旁令,掌握MySQL進階內容,完成銀行自動提款機系統實戰、此盯英漢詞典、歌詞解析器等項目。
第二階段WEB全棧。這一部分主要學習Web前端相關技術,你需要掌握HTML、CSS、JavaScript、jQuery、BootStrap、Web開發基礎、VUE、Flask Views、Flask模板、 資料庫操作、Flask配置等知識。
學習目標:掌握WEB前端技術內容,掌握WEB後端框架,熟練使用Flask、Tornado、Django,可以完成數據監控後台的項目。
第三階段數據分析+人工智慧。這部分主要是學習爬蟲相關的知識點,你需要掌握數據抓取、數據提取、數據存儲、爬蟲並發、動態網頁抓取、scrapy框架、分布式爬蟲、爬蟲攻防、數據結構、演算法等知識。
學習目標:可以掌握爬蟲、數據採集,數據機構與演算法進階和人工智慧技術。可以完成爬蟲攻防、圖片馬賽克、電影推薦系統、地震預測、人工智慧項目等階段項目。
第四階段高級進階。這是Python高級知識點,你需要學習項目開發流程、部署、高並發、性能調優、Go語言基礎森燃和、區塊鏈入門等內容。
學習目標:可以掌握自動化運維與區塊鏈開發技術,可以完成自動化運維項目、區塊鏈等項目。
按照上面的Python學習路線圖學習完後,你基本上就可以成為一名合格的Python開發工程師。當然,想要快速成為企業競聘的精英人才,你需要有好的老師指導,還要有較多的項目積累實戰經驗。
自學本身難度較高,一步一步學下來肯定全面且扎實,如果自己有針對性的想學哪一部分,可以直接跳過暫時不需要的針對性的學習自己需要的模塊,可以多看一些不同的視頻學習。

⑧ tornado 協程 中支持mysql 非同步請求嗎

用tornado畢竟是可以做非同步request的, 如果你的資料庫真的很慢, 不如再開其他的tornado做block資料庫操作(你可以用tornado wsgi多線程/多進程形式部署, 也可以用絕虛django, flask等), 然後通過API的形式將資料庫返回過來. 相當於用tornado給你的資料庫操作web化(寫內部數據API)

這個是我剛才剛剛想到的, 原理就是用一些獨立的進中團程去做費時的資料庫操作, 這樣你的主web tornado進程就可以非同步暢通, 增加吞吐量. 這樣就不需要為各個資料庫寫驅動了.

如果資料庫在不同的機器上, 那麼可以考慮將賣宏橘這些獨立的數據操作tornado進程在資料庫機器上部署. 使用wsgi多線程/多進程的好處是查詢可以同時進行, 當然也可能卡死資料庫. 使用tornado自己的單進程非同步部署的時候, tornado還可以充當一個資料庫操作隊列的作用.

⑨ 風變編程的Python課程學完效果如何

一、Python簡介

Python是一種用來編寫應用程序的高級程序設計語言,TIOBE程序語言排行榜2015年12月的排名如下:

Python實現強勢逆襲,而且我相信,隨著時間的推移,國內Python語言未來前景也是一片向好。

Python的特點是優雅簡單,易學易用(雖然我感覺還是有一些概念不容易理解),Python的哲學是盡量用最少的,最簡單易懂的代碼實現需要的功能。Python適宜於開發網路應用,腳本寫作,日常簡單小工具等等。Python的缺點是效率較低,但是在大量的場合效率卻不是那麼重要或者說Python不是其性能瓶頸,所以不要太在意。其次是2.x-3.x的過渡使得許多3.x還缺少很多2.x下的模塊,不過也在完善中。其次就是源代碼無法加密,發布Python程序其實就是發布源代碼。

二、基礎語法要點

1.如果一個字元串中有許多需要轉義的字元,而又不想寫那麼多'',那麼可以用 r'...' 表示 '...'內的內容不轉義。

2.Python可用'''...'''來表示多行內容,如:

123456

>>>print('''line1line2line3''')line1line2line3

3.Python的邏輯運算and, or, not 分別對應C語言中的&&, ||, !.

4.Python的整數與浮點數大小都沒有范圍。

5.Python中除法有兩種: '/'除出來必是浮點數, '//'除出來是整數,即地板除。

6.Python中一切皆引用。每個對象都有一個引用計數器(內部跟蹤變數)進行跟蹤,引用計數值表示該對象有多少個引用,當初次產生賦給變數時,引用計數為1,其後沒進行下列行為中的任意一種都會增加引用計數:

123

賦值: a=b用作函數參數傳遞: func(a)成為容器對象的一個元素: lis=[1,2,a]

以下任意一種行為都會減少引用計數:

1234

del銷毀:dela變數另賦給其他對象:a=False對象從容器中刪除: lis.remove(a)身在的容器被銷毀:dellis

7.深拷貝與淺拷貝的概念與對比,有點復雜,看這篇文章

8.list,tuple和dict,set

list:為列表,是一個有序集合,類似於數組但又比數組功能強大,可以隨時append,pop元素,下標從0開始,且下標為加n模n制,即lis[-1] = lis[len-1],下標范圍[-len,len-1].

tuple:為元組,類似於list,但list為可變類型,而tuple不可變,即沒有append,pop等函數。一個建議是為了安全起見,能用tuple代替list盡量用tuple。如果tuple只有一個元素,要寫成如(1,)以避免歧義。

dict:字典類型,存放key-value鍵值對,可以根據key迅速地找出value,當然,key必須是不可變類型,如下是錯誤的:

12345

>>> dic={[1,2]:'value'}Traceback (most recent call last):File"<pyshell#10>", line1,in<mole>dic={[1,2]:'value'}TypeError: unhashabletype:'list'

list與dict的優劣對比:

1234567

dict:1.插入,查找速度快,跟key的數目無關2.需佔用大量內存,內存浪費嚴重list:1.插入,查找速度慢,O(n)的復雜度,隨元素個數增加而增加2.佔用內存小

dict內部存放的順序和key放入的順序是沒有關系的

set:set與dict類似,相當於只有key沒有value的dict,每個key不同,set間有 &, | 等操作對應集合的交,並操作。

三、函數

1.函數是對象,函數名即是指向對應函數對象的引用,所以可以將函數名賦給一個變數,相當於給函數起一個『別名』。

123

>>> mmm=max>>> mmm(1,2,3)3

2.Python函數可以返回」多個值「,之所以打引號,是因為實際上返回的多個值拼成了一個元組,返回這個元組。

3.定義默認參數需要牢記:默認參數必須指向不變對象。否則第一次調用和第二次調用結果會不一樣,因為可變的默認參數調用後改變了。

4.可變參數:傳入的參數個數是可變的,可以是0個或多個。可變參數會將你傳入的參數自動組裝為一個tuple。在你傳入的list或tuple名字前加一個 * 即說明傳入的是可變參數。習慣寫法為*args。

5.關鍵字參數:傳入0個或多個含參數名的參數,這些參數被自動組裝成一個dict。習慣寫法**kw,如**a表示把a中所有的鍵值對以關鍵字參數的形式傳入kw,獲得一個dict,這個dict是a的一份拷貝,對kw改動不會傳遞到a

6.命名關鍵字在函數定義中跟在一個*分割符後,如

12

deffunc(a,b,*,c,d):pass

c,d為命名關鍵字參數,可以限制調用者可以傳入的參數名,同時可以提供默認值。

7.參數定義順序:必選參數,默認參數,可變參數/命名關鍵字參數,關鍵字參數。

8.切片操作格式為lis[首下標:尾下標:間隔],如果都不填,即lis[::]則代表整個容器lis

9.用圓括弧()括起來一個列表生成式創建一個生成器generator,generator保存生成演算法,我們可以用next(g)取得生成器g的下一個返回值。生成器的好處就是我們不需要提前生成所有列表元素,而是需要時再生成,這在某些情況下可以節省許多內存。演算法也可以不是列表生成式而是自定義函數,只需在函數定義中包含yield關鍵字。

10.map()和rece(): 二者都是高階函數。map()接收兩個參數,一個是函數,一個是Iterable序列,map將傳入的函數依次作用在序列每一個元素上,並把結果作為新的Iterator返回。rece()類似累積計算版的map(),把一個函數作用在一個序列上,每次接收兩個參數,將結果繼續與序列的下一個元素做累積計算。

利用map和rece編寫一個str2float函數,如把字元串'123.456'轉換成浮點數123.456:

123456789101112131415

(s):deff1(x,y):returnx*10+ydefchar2num(s):return{'0':0,'1':1,'2':2,'3':3,'4':4,'5':5,'6':6,'7':7,'8':8,'9':9}[s]deff2(x,y):returnx*0.1+ya,b=s.split('.')print('a=',a)print('b=',b)returnrece(f1,map(char2num,a))+0.1*rece(f2,map(char2num,b[::-1]))print('str2float('123.456') =', str2float('123.456'))

11.fliter()函數過濾序列,類似於map()作用於每一元素,根據返回值是True或者False決定舍棄還是保留該元素。函數返回一個Iterator。

12.sorted()函數可實現排序,類似於C++庫中的sort()函數,但是比其更加簡潔,語法為sorted(lis,key=func,reverse=T/F)

key函數可實現自定義的排序規則,reverse表示升序還是降序。

13.一個函數可以返回一個函數,但是返回時該函數並未執行,所以返回函數中不要引用任何可能發生變化的變數,否則會出現邏輯錯誤。

14.裝飾器(decorator): 當需要增強函數的功能卻不希望修改函數本身,那麼可以採用裝飾器這種運行時動態增加功能的方式,增加的功能卸載裝飾器函數中。如在執行前後列印'begin call'和'end call',可以這樣做:

12345678910111213141516

importfunctoolsdeflog(func):@functools.wraps(func)#為了校正函數簽名,最好寫上defwrapper(*args,**kw):print('begin call')f=func(*args,**kw)print('end call')returnfreturnwrapper@logdefhah():print('hahahaha')hah()

123

begin callhahahahaend call

15.偏函數: functools.partial(),作用是將一個函數的某些參數固定住,作為新函數的參數,即固定住該參數,返回一個新函數,使調用更簡單。

四、面向對象編程

1.Python實例變數可以自由地綁定任何屬性

2.為了不讓內部屬性不被外部訪問,在屬性的名稱前加上兩個下劃線__,這樣就變成了一個私有變數(private),注意,不能直接訪問不代表一定不能訪問,事實上,加雙下劃線後Python就會將其改名為『_class名__name』,所以還是可以這樣來訪問這個『私有』變數。

3.對於靜態語言,如果要求傳入一個class類型的對象,那麼傳入的對象必須是class類型或者其子類,否則將無法調用class中的方法,而Python這樣的動態語言有『鴨子類型』一說,即不一定要傳入class類型或其子類,而只要保證傳入的對象中有要使用的方法即可。

4.如果想要限制實例可以綁定的屬性,那麼在定義class時定義一個__slots__變數即可,例如:

12

classStudent(object):__slots__=(『name』,』age』)

注意,__slots__限制的屬性對當前類實例起完全限製作用,且與子類共同定義其__slots__,也就是說子類可以定義自己的__slots__,子類實例允許定義的屬性就是自身的__slots__加上父類的__slots__,即並集。

5.@ property裝飾器可以使一個getter方法變成屬性,如果方法名為me,那麼@me.setter裝飾器則可使一個setter方法變成屬性。這樣可以使代碼更簡短,同時可對參數進行必要的檢查。

6.通過多重繼承,可使子類擁有多個父類的所有功能。

7.在類中__call__方法可使實例對象像函數那樣直接調用,作用即是該方法定義的過程。

8.ORM(Object Relational Mapping 對象關系映射),就是把關系資料庫的一行映射為一個對象,也就是一個類對應一個表。ORM的實現需要通過metaclass元類修改類的定義。元類可以改變類創建時的行為。

五、調試

1.Python調試方法:

(1)直接列印

(2)斷言

(3)pdb

(4)IDE

六、IO編程

1.序列化: 把變數從內存中變成可存儲或傳輸的過程稱之為序列化。Python用pickle模塊實現序列化。序列化之後,就可以把序列化後的內容存儲到磁碟上或者通過網路進行傳輸。pickle.mps()將對象序列化成一個bytes,而pickle.loads()可以根據bytes反序列化出對象。

2.pickle雖好,但是它專為Python而生,所以要在不同語言間傳遞對象,最好還是xml或者json,而json表示格式是一個字元串,更易讀取,且比xml快,所以更加適宜於對象序列化。Python內置了json模塊,相應方法仍然是mps()和loads()。

3.但是在默認情況下,有些對象是無法序列化的,所以我們有時還需要定製轉換方法,告訴json該如何將某類對象轉換成可序列為json格式的{}對象。如下即是一個轉換方法:

123456

defmantodict(std):return{'name': std.name,'age': std.age,'id': std.id}

七、進程與線程

1.Python用mutiprocessing模塊來實現多進程。

2.如果要大量創建子進程,可以使用進程池:

1

frommultiprocessingimportPool

示例如下:

12345678

....p=Pool(4)foriinrange(5):p.apply_async(long_time_task, args=(i,))print('Waiting for all subprocesses done...')p.close()p.join()print('All subprocesses done.')

要使用進程池需新建Pool對象,對Pool對象調用join()使等待池中所有子進程運行完畢,調用join()方法之前必須調用close(),且此後無法再新加子進程。

3.使用subprocess模塊可以方便的啟動並管理一個子進程,控制其輸入輸出。

4.進程間通信使用Queue,Pipes實現。

5.threading模塊管理線程。threading.lock()創建線程鎖,防止同時訪問互斥資源造成的錯誤,示例如下:

1234567

lock=threading.Lock()...lock.acquire()...change(mutex)...lock.release()

6.ThreadLocal可以解決參數在一個線程中各個函數之間互相傳遞的問題。

7.managers模塊實現分布式進程。

八、正則表達式與常用內建模塊

1.re模塊進行正則表達式編譯和匹配,如果該表達式需要匹配很多次,那麼最好進行編譯從而大大節省時間。

正則表達式匹配郵箱例子:

12345678910

importrehah=re.compile('[0-9a-zA-Z]+[.[0-9a-zA-Z]+]*@[0-9a-zA-Z]+.[a-z]{2,3}')print(hah.match('[email protected]').group())print(hah.match('[email protected]').group())i=1whilei <10:r=input('請輸入郵箱:')print(hah.match(r).group())i=i+1

2.datetime模塊進行日期和時間的處理,每一個時間對應一個timestamp,我們把1970年1月1日 00:00:00 UTC+00:00時區的時刻稱為epoch time,記為0(1970年以前的時間timestamp為負數),當前時間就是相對於epoch time的秒數,稱為timestamp。字元串和datetime也可以相互轉換,採用strptime()方法,字元串轉換為datetime時需要設定一個識別格式,其中

1

%Y-%m-%d%H:%M:%S

分別表示年-月-日 時-分-秒。

從datetime得出月份,星期等字元串用strftime()方法,其中:

1

%a,%b%d%H:%M

分別表示星期, 月份 日期 時:分。

示例:

12345678910

fromdatetimeimportdatetimer='2015-11-23 12:01'dt=datetime.strptime(r,'%Y-%m-%d %H:%M')print(dt)week=dt.strftime('%a %b %d, %H:%M')print(week)2015-11-2312:01:00Mon Nov23,12:01

3.collections是Python內建的一個集合模塊,提供了許多有用的集合類。

4.Base64是一種任意二進制到文本字元串的編碼方法,常用於在URL、Cookie、網頁中傳輸少量二進制數據。

5.struct模塊用來解決bytes和其他二進制數據類型的轉換。

6.Python的hashlib提供了常見的哈希演算法,如MD5,SHA1等等。hashlib實現簡單登錄:

importhashlibdb={'michael':'','bob':'','alice':''}defget_md5(ostr):md5=hashlib.md5()md5.update(ostr.encode())returnmd5.hexdigest()deflogin(user, password):r=get_md5(password)fornameindb:ifdb[name]==r:returnTruereturnFalseprint(login('bob','abc999'))True

7.Python的內建模塊itertools提供了非常有用的用於操作迭代對象的函數。

8.urllib提供了一系列用於操作URL的功能。如GET,POST...

9.PIL(Python Imaging Library Python圖像庫)是一個強大的圖像處理標准庫,功能強大卻又簡單易用。現在的名字叫做Pillow。可以如下安裝Pillow:

1

pip3 install pillow

從下面生成數字驗證碼的程序可以窺其一斑:

九、網路編程和電子郵件

1.網路編程主要是TCP和UDP的編程,示例見【Python網路編程】利用Python進行TCP、UDP套接字編程

2.SMTP是發送郵件的協議,Python內置對SMTP的支持,可以發送純文本郵件、HTML郵件以及帶附件的郵件。Python對SMTP支持有smtplib和email兩個模塊,email負責構造郵件,smtplib負責發送郵件。Python內置一個poplib模塊,實現了POP3協議,可以直接用來收郵件。由於現在絕大多數大型郵件服務商都採取了反垃圾郵件措施,所以這部分的簡單實驗並沒有成功,還需進一步研究,等遇到具體情況再說。

3.Python內嵌了sqlite資料庫,還可以自行安裝連接mysql,MySQL是當前最流行的開源資料庫,在行業內有著廣泛的應用。

十、Web開發和非同步IO

1.WSGI(Web Server Gateway Interface) 伺服器網關介面。

2.Python web 開發框架:

-Flask:流行的Web框架

-Django:全能型Web框架

-web.py:一個小巧的Web框架

-Bottle:和Flask類似的Web框架

-Tornado:Facebook的開源非同步Web框架

3.協程

⑩ 什麼是Python全棧工程師

全棧工程師是指掌握多種技能,並能利用多種技能獨立完成產品的人。也叫全端工程師,英文Full Stack
developer。
當下全棧工程師的概念很火,而Python是一種全棧的開發語言,所以你如果能學好Python,那麼前端,後端,測試,大數據分析,爬蟲等這些工作你都能勝任。

閱讀全文

與pythontornado協程相關的資料

熱點內容
安卓手機沒有聲音均衡器怎麼辦 瀏覽:504
吃雞國際服為什麼會伺服器匆忙 瀏覽:246
微信中如何打開定位伺服器 瀏覽:203
java並發編程書籍 瀏覽:280
android601源碼 瀏覽:788
程序員離職了還能幹嘛 瀏覽:156
少林功法pdf 瀏覽:471
安卓80版本小游戲怎麼玩 瀏覽:632
奇書pdf 瀏覽:836
伺服器的管理口有什麼用 瀏覽:641
澳洲加密資產新政策 瀏覽:155
哈利波特連接伺服器失敗什麼意思 瀏覽:234
提取手機上安裝的app並反編譯 瀏覽:964
人工智慧演算法書 瀏覽:604
安卓如何傳輸圖片給蘋果 瀏覽:829
可編程式控制制器原理應用網路 瀏覽:587
社畜解壓是什麼意思 瀏覽:436
吉利博越用哪個app啊 瀏覽:513
西安單片機晶振電容 瀏覽:187
分地面積的演算法 瀏覽:179