欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

筆者帶你剖析Python3.x

系統 1700 0

筆者帶你剖析Python3.x 《筆者帶你剖析Python3.x》

?

前言

其實不太想寫跟Java無關的東西,但是實在憋得難受,想想一個項目組的其他同事都回家過年了,就剩下我一個苦逼的還在堅守在戰斗一線,醬油也打了一段時間了,再憋下去難受了,所以趁著過年前發一篇博文吧,也可以打發下時間,何樂而不為呢?

?

廢話說了一籮筐,回到正題。Python相信有不少開發人員,尤其是運維人員應該是非常熟悉的,那么請大家聽我好好掰扯下Python究竟能夠做什么,如果你覺得Python是個好東西,那么也請你嘗試著使用它為你的項目增添一點色彩。筆者本文所使用的Python版本為3.x,盡管和Python2.x相比,3.x 在語法層面的改變是比較大的,但是請大家不要去 糾結 這些問題,只需要聽筆者為你一一道來即可。

?

目錄

一、Python簡介;

二、Python的下載與安裝;

三、第一個Python程序;

四、基本語法的使用

五、函數的使用;

六、流程控制語句;

七、面向對象特性;

八、I/O操作;

九、線程操作;

?

一、Python簡介

其實看筆者這篇博文的朋友,更關心的是Python是什么,以及究竟能夠為我們的項目帶來什么好處?其實筆者在第一次接觸Python的時候,立馬就被這 炫酷和簡易 的語法吸引住了,因為使用Python所帶來的好處太多了。簡單來說,Python其實是一門基于 解釋性/編譯性 的動態、面向對象編程語言,這里筆者要稍微解釋下所謂的解釋性/編譯性問題。對Java有所了解的開發人員應該知道,JIT編譯器所帶來的改變對于Java程序的運行性能是起到了 至關重要 的作用,使得Java程序的運行性能有了 質的飛躍 ,毫 不遜色 于C/C++編寫的程序的執行性能,這是因為HotSpot VM中的JIT編譯器會在運行時結合 熱點探測功能 將頻繁被調用的代碼標記為“ 熱點代碼 ”然后經過 分層優化編譯技術 將Java代碼直接 編譯為本地代碼。這種運行時的編譯技術,必然比靜態編譯擁有更好的 編譯質量 ,畢竟 靜態編譯是無法準確預估程序在執行過程中所有的運行時熱點的

?

和Java一樣,Python的執行引擎究竟是基于解釋執行呢,還是編譯執行,或者是混合執行都取決于底層的VM(筆者博文全部統稱為VM)。目前比較常見的Python VM有:CPython、IPython、PyPy,以及Jython(HotSpot VM)。關于這幾個VM大家可以去官網了解下。簡單來說,CPython是Python的官方缺省解釋器,基于解釋運行;而IPython是建立在CPython之上的一個交互式解釋器;PyPy內置有JIT編譯器,執行性能相對而言會比前幾種高效許多倍;而Jython其實就是將Python代碼編譯為字節碼后運行在HotSpot VM中,結合HotSpot VM的解釋器+JIT編譯器的 混合執行引擎 ,可以達到高效執行的效果,不過更重要的是使用Jython可以很好的與Java代碼交互(并不僅限于特定的語言,CPython可以是C、C++)。是的,你沒有聽錯,簡單到你會以為Python天生就是為了粘合Java代碼而生!因此Python還有一個很好聽的名字,那就是“ 膠水語言 ”。

?

當然不是說Python語言的作用就是純粹的粘合其他語言一起執行,盡管Python最大的優點確實是這個,但是任何高級語言能做的事情,Python都能夠做到,而且 代碼產出效率極快 。因此大部分企業都會在項目需求較緊的時候使用Python快速上線,然后后續逐漸使用其他適合的編程語言逐步替換之前由Python編寫的功能模塊,以此保證代碼的 結構嚴謹性

?

二、Python的下載與安裝

如果你Java功力很強,那么學習Python就是輕而易舉,這就好比《倚天屠龍記》中的張無忌掌握九陽神功后,學習太極拳的輕車熟路,其實道理都是 一樣 的。當然如果你本身骨子里并無任何編程語言基礎,學習Python同樣也 不會感覺到吃力 ,因為相對于Java\C\C++之類的編程語言,Python的學習可以算是相當簡單的。如果按照筆者的經驗來判斷,除了比HTML稍微復雜點,幾乎 是個人都能夠輕而易舉的掌握Python這門語言 。筆者甚至在考慮,過年回家的時候,是否有必要教老媽使用Python編寫一個小程序?

?

又說了一大堆廢話,回到主題,Python的下載和安裝。大家可以登錄 https://www.python.org/ 下載Python,筆者本文所使用的版本并沒有采用最新的3.4.2,而是3.3.0,沒有特殊的寓意,因此你可以自由選擇和筆者保持一致的版本,同樣也可以下載最新的版本,當然千萬不要下載Python2.x版本,畢竟它們在語法層面上的差距是非常大的。

?

當成功下載好Python后,在安裝的時候記得勾選選項“path”,否則只能夠在安裝好后,手動配置Python的環境變量(PATH=安裝路徑)。當大家成功安裝好Python后,為了檢驗是否安裝成功,大家可以通過控制臺,輸入命令“Python -V”(大寫V, Python大小寫敏感 )驗收結果,如果控制臺輸出的是Python的版本號,則意味著安裝成功,反之安裝失敗。

?

三、第一個Python程序

所謂工欲善其事必先利其器,在使用Python編寫程序之前,首先要做的就是準備好Python的開發工具,當然筆者不建議新手一上來就是用各種IDE,而是建議你使用文本編輯器就可以了,比如Editplus,它會是你初次接觸Python的利器,希望大家記住, 學習任何一門新技術,或者新語言之前,必然首先需要記住一些常用的函數、語法風格 ,而不是什么都是依靠IDE工具來“飯來張口,衣來伸手”,不要讓你的大腦過度偷懶,會生銹的。

?

當然如果你使用Python有一斷時間了,或者正在準備使用Python運用在項目中時,就有必要考慮工作效率的問題了,因為筆者也不希望你浪費過多的時間在回憶應該調用那個函數,以及函數的名字叫什么,否則你可能離打包走人不遠了。簡單來說,Python的IDE工具非常多,如果是JYthon,那么使用PyDEV是非常好的,以插件的形式集成在神器Eclipse中,無疑為Java開發人員帶來了方便。當然本文只是單純的講解Python的使用,并且VM也是使用CPython,因此Pycharm不得不說是編寫Python的好幫手。

?

筆者不打算啰嗦的為大家科普IDE工具應該怎么使用,請自行Google。當成功啟動IDE工具或者文本編輯器后,接下來我們就開始編寫我們的第一個Python程序,如下所示:

      print("Hello World")
    

?

當執行上述程序時,控制臺將會輸出“Hello World”。納尼,你沒有看錯,Python就是這么簡單, 嚴格意義上按照模塊進行劃分,不需要顯式的先編寫一個類、在編寫方法,再來寫語句 。嗦嘎德斯捏。

?

Sorry,筆者忘記了一件事情,按照慣例不應該先講如何在IDE工具中或者文本編輯器中編寫Python代碼,而是應該讓大家知道Python的交互式運行環境。沒關系,現在講似乎也不遲。Python其實有2種類型的運行環境,一種是基于交互式環境,而另外一種則是我們剛才使用到的傳統環境。這里筆者所指的交互式環境,其實更多應用在測試、練習上,適合剛接觸Python的開發人員,畢竟在交互式環境中,寫一行代碼,立馬就可以得到結果,如下所示:

筆者帶你剖析Python3.x

?

除了在剛開始學習Python的時候,或者在測試練習上會使用到Python自帶的交互式環境外,實際的項目開發過程中,這種做法并不常見,因為代碼 無法固化 ,每次都要重新編寫,意義何在?

?

四、基本語法的使用

筆者在本節中將會介紹Python的基本語法的使用,涵蓋了:變量的定義、運算符、表達式、數據類型、數據結構等知識點。請不要責怪筆者的“ 不耐煩 ”,畢竟這些太過于基礎的技術,筆者實在是不忍心 大費周章 ,浪費紙墨和口水去講解,畢竟后續還有其它的知識點,因此快速講解是筆者的風格,希望理解。

?

簡單來說,變量其實就是屬性(后續重點講解);運算符其實用于計算,表達式由字面值、云算法和變量構成;數據類型很簡單,跟Java一樣,Python同樣也是 強類型 的,不過在Python中定義一個變量,開發人員并不需要在變量標示符之前顯式聲明變量的類型( PS:不顯式定義變量類型導致筆者曾經一度以為Python是弱類型,結果試了下10+“100”,運行期報錯,OK,糾正下這個錯誤 );數據結構簡單來說就是數據的存儲結構和存儲方式。下面筆者使用一段簡單的代碼來匯總筆者本節提及過的所有知識點,如下所示:

      #encoding=gbk
#Python的基本語法結構
userName="JohnGao"
age=28
sex=True
hobbys=["看書","寫字","睡覺"]
print("我的名字->" + userName)
print("我的年紀->" + str(age))
print("我的性別->" + str(sex))
for hobby in hobbys:
    print("我的愛好->"+hobby,end="\t")
    

?

上述程序示例中,將會按照筆者書寫的順序串行執行print輸出。可以發現,在Python中,確實是大小寫敏感的,boolean類型的值,True和False首字母是必須要大寫;而筆者在輸出int類型和boolean類型的2個變量時,使用了強轉,因為Python的一條語句輸出, 只能是同一種數據類型 ,而不能夠是多種(除非符號“,”分割)。關于筆者定義的線性表的數據結構來存儲數據結果集,然后又使用for循環的方式將其迭代,關于這一點,筆者稍后會做出解釋。

?

五、函數的使用

函數即方法 。除了可以在代碼中使用Python提供的缺省內置函數外,開發人員也可以編寫自定義函數來實現程序的功能。當然在正式開始講解如何在程序中編寫一個自定義函數之前,我們首先來看看Python究竟帶給了我們哪些驚喜?筆者示例幾個比較常用的Python內置函數,如下所示:

      #encoding=gbk
#求絕對值函數
print(abs(-100))
#強制轉換函數
print(str(100))
print(int("200"))
print(float(2000))
print(bool(1))
#isinstance函數
print(isinstance(100,(int,float)))
    

?

上述程序示例中abs()函數的作用就是用于求絕對值,比如字面值-100的絕對值就是100;而強制轉換函數的作用無非就是將一種數據類型轉向另外一種數據類型,當然如果是float轉向int,由于int無法存儲小數,必然 精度會丟失 ;至于isinstance()函數其實就是類似于Java的instanceof()方法,目的就是檢測當前類型是否跟目標類型一直,該函數除了可以作用于基本數據類型外,還支持引用類型。
?
當大家了解了Python的一些常用的缺省內置函數后,接下來我們再來學習如何在程序中編寫自定義函數,以滿足特定的程序功能。其實在Python中定義一個自定義函數非常簡單,我們都知道在Java中定義一個方法無非就是使用void關鍵字或者返回值進行標示,而在Python中則是使用關鍵字def進行標示,如下所示:
      def testMethod1():
    print("一個簡單的自定義函數")

#定義一個無任何操作的空函數
#pass關鍵字就是一個占位符
def testMethod2():
    pass
    
上述代碼示例中,方法是沒有顯式帶有返回值的,那么如果希望方法具有返回值時應該怎么辦呢?其實在Python中,開發人員無需顯式的定義返回值類型,當一個函數執行完成后希望有返回值進行返回時,可以使用關鍵字return。在此大家需要注意, 如果一個函數內部并沒有顯式的通過return關鍵字指定有返回值時,Python缺省將會返回一個None值 。如下所示:
      def testMethod1():
   value=100+1
   return value
print(testMethod1())

    
大家是否曾想過Java方法能否支持 多返回值 ?很抱歉,目前Java語法層面并沒有提供這種支持,不過在Java中就真的沒有辦法一次性返回多個參數嗎?其實不然,當我們返回一個數組或者集合類型的時候其實就是間接返回了多個參數,基于這個想法,Python的函數可以友好的“支持”多返回值。如下所示:
      def testMethod1():
   value1=100+1
   value2="userName->JohnGao"
   return value1,value2
value1,value2=testMethod1()
print(value1,value2)
print(testMethod1())
    
其實Python所謂的多返回值, 無非就是返回一個數組類型 。除了返回值之外,接下來我們再來看看如何定義函數參數以及函數的可變參數,如下所示:
      #定義函數參數
def testMethod1(userName,age):
   return userName,age
userName,age=testMethod1("JohnGao",28)
print(userName,age)
#定義可變參數
def testMethod1(*values):
    for value in values:
        print(value,end="\t")
testMethod1(100,200,300)
    
六、流程控制語句
流程控制語句其實光聽名字都猜得出一個大概,無非就是 控制程序的執行流程 。本小節筆者會重點為大家介紹如何使用Python編寫if-else、if-else-if多路分支、for循環,以及while循環等語句。廢話不多說,首先來看一個簡單的示例,如下所示:
      #if-else語句
value = 50
if value < 10:
    pass
else:
   pass
#if-else-if多路分支語句
userName=input("猜猜我的名字:\n")
if userName == "JohnGao":
    pass
elif userName=="JohnGao1":
    pass
else:
    pass
#for循環語句
for i in range(10):
    pass
value2=["1","2","3"]
for j in value2:
    pass
#while循環語句
value3=0
while value3<10:
   value3+=1
    
其他話就不多說了,相信大家都能夠看懂筆者上述程序示例。既然都已經講解到第6小節了,相信細心的讀者已經發現了,Python和Java在語法層面上確實存在一些細微的差別,但是基本上有Java功底的開發人員都能夠讀懂和理解Python代碼所想闡述的意思。不知大家是否還記得,讀大學那會,你們的老師經常告訴你們一定要注意 編碼規范 ,代碼一定要 四格縮進 ,這樣的代碼 可讀性 才會更好,畢竟一個團隊,項目的代碼并不是你一個人在寫。但是在Java中,代碼的四格縮進僅僅只是一個可讀性上面的 非硬性要求 ,哪怕你并不遵守,也不會影響程序 語義
?
和Java恰恰相反,Python算是將四格縮進 發揚光大 了,由于Python中代碼塊并沒有使用符號“{}”進行概括,因此依靠四格縮進就算是Python語法的一種 隱式 代碼塊的概括,大家在使用Python進行編碼的時候一定要非常注意,否則你將會有意想不到的蛋疼問題等著你。
?
七、面向對象特性
面向對象的思想如今已經滲透到軟件開發的 各個領域 ,例如:OOA(Object Oriented Analysis,面向對象的分析)、OOD(Object Oriented Design,面向對象的設計),以及開發人員時常掛在嘴邊的OOP(Object Oriented Programming,面向對象的編程)。簡單來說,面向對象的概念就是類和對象,而面向對象的特性就是封裝、繼承和多態。
?
總規一點,使用面向對象編程,最大的好處就是能夠輕而易舉的實現 代碼復用 。類是一個抽象的概念,所代表的含義其實就是某一類事物,比如動物這個就算是一個類;而對象就是類的一個具體實例。比如:老虎、獅子、大象等,在一個對象中,屬性(即變量)代表了對象的各種 器官 ,而方法則代表了對象的一系列 行為 。明白這一點后,我們再來看面向對象的3個特性,從封裝開始,在開發過程中,如果有一些通用的控制邏輯,或者業務邏輯(統稱為組件),我們是否需要將其封裝在一個類中,然后在需要的時候調用即可,而不必翻來覆去的重復編寫,因此類就是最基本的 封裝單元 。試想一下,既然通用性的組件封裝好后,接下來的任務就是使用,采用繼承的方式使用封裝好的組件就是一個不錯的方式,并且一旦繼承后,面向對象的多態性則體現了出來。所謂的多態,大家千萬不要只是簡簡單單的理解為方法的重載(override)和重寫(overwrite),否則會顯得非常膚淺。多態簡單來說其實就是 晚期綁定的一種形式 ,既然發生在運行期,那么對象之間的引用必然就 不是編譯期可知的靜態鏈接 ,而是動態鏈接,因為無法在編譯期確定下來的引用關系,則只能夠在運行期進行綁定,比如Java中的 里氏替換原則 就是一個很好的例子。
?
Python對面向對象的支持和其他高級編程語言一樣,都是支持的非常完善。在程序中,定義一個類使用的是關鍵字class,如下所示:
      class Animal(object):
    pass

    
和Java一樣,Python中所有類型的超類就是object。然而如果是顯式繼承其他超類的話,我們則可以在類名標示符的符號“()”定進行標注,如下所示:
      #繼承示例
class Animal(object):
    pass
class Tiger(Animal):
    pass
class Pig(Animal):
    pass
    
接下來我們來看一個晚期綁定的例子,如下所示:
      #晚期綁定
class Animal(object):
    def getName(self):
        pass
class Tiger(Animal):
    def getName(self):
        print("我的名字叫做Tiger")
class Pig(Animal):
     def getName(self):
         print("我的名字叫做Pig")
def getName(Animal):
    print(Animal.getName())
#創建對象實例
animal = Tiger()
getName(animal)

    
上述程序示例中,筆者調用getName()方法時,由于在編譯期根本無法確定所傳遞進來的參數究竟是Animal還是他的子類,因此也就意味著 編譯期可變 ,自然也就無法使用前期綁定的方式。在Python中,為一個類型創建其對象實例并不需要像Java一樣顯式的使用關鍵字new,隱式的創建一個類的對象實例或多或少減少了開發人員的編碼量。 在本小節的結尾處,筆者再跟大家浪費點口水闡述下Python的訪問修飾符。在Java中,開發人員可以使用public、private或protected等關鍵字定義類成員的 可見性 ,但是在Python中,則可以使用符號“--”將其類成員定義為私有,而缺省就是public的,如下所示:
      class Demo(object):
    userName="張三"
    __passWord="123456"
    def getName(self):
        pass
demo = Demo()
print(demo.userName)
#print(demo.passWord)
    
上述程序示例中,passWord變量的可見性僅限于Demo內部,而無法被外界 感知 到。其實說了這么多,筆者似乎已經零零散散的介紹過Python的大部分語法了,但回想一下,既然變量都已經談到了,那么常量是不是也要拉出來曬一曬?在Java中定義一個常量需要使用關鍵字final進行標示,然后標示符名稱使用大寫的形式標示所定義的字段是一個常量,而Python并不需要顯式的使用final關鍵字進行標示,因為Python壓根就 沒有真正意義上的常量 ,僅僅只是一種規范性的 約定 ,約定什么呢?就是約定Python中所謂的常量標示符全部都使用大寫,但是這個常量并非真正意義上的常量,值是可變的,因此Python中的常量即“ 偽常量 ”。
?
八、I/O操作
I/O(Input/Output)技術,是最容易被大部分web開發人員所忽略的,其實I/O技術算得上是與開發人員打交道最 頻繁 的技術之一,哪怕你沒有在程序中顯式的使用I/O,你仍然也在不知不覺中 間接 使用到了。比如當我們打開電腦的時候,需要從磁盤中讀取操作系統的系統文件、打開瀏覽器上網時、QQ或者微信聊天時都間接或者直接的使用到了I/O技術。而在項目研發過程中,Tomcat中大量的I/O操作只是你自己渾然不知而已,所以了解并熟練掌握I/O技術的使用是每一個程序員 必備 的技能之一。

向目標數據源讀取數據:

筆者帶你剖析Python3.x

?

向目標數據源寫入數據:

筆者帶你剖析Python3.x

那么什么是I/O 呢?所謂I/O 指的就是數據輸入/輸出的過程,我們稱之為流(數據通信通道)這個概念。比如當Python應用程序需要讀取目標數據源的數據時,則開啟輸入流。當需要寫入時,則開啟輸出流。數據源可以是本地磁盤、內存或者是網絡中的數據。Python語言定義了2 種類型的流:字節流(以byte 為單位讀/寫數據)和字符流(以char 為單位讀/寫數據)。字節流為處理字節數據的輸入/輸出提供了方便的方法,常用于讀/寫二進制數據。字符流則為處理字符數據的輸入/輸出提供了方便的方法。并且在某些情況下,使用字符流比使用字節流顯得更為高效。
?
接下來筆者開始為大家演示如何使用I/O技術讀取目標數據源的數據和向目標數據源寫入數據(以字符為單位),如下所示:
      #讀取目標數據源的數據
try:
    readValue=open("d:/test.txt","r")
    #讀取一行字符串
    print(readValue.readline())
finally:
    if readValue:
        readValue.close()
#向目標數據源寫入數據
try:
    writeValue=open("d:/test2.txt","w")
    #寫入一行字符串
    writeValue.write("test...")
finally:
    if writeValue:
        writeValue.close()
    
上述程序示例中,筆者使用的是readLine()函數每次讀取目標數據源的一行字符串數據,但是如果有多行數據時應該怎么辦呢?2個辦法,那么使用read()函數一次性讀完,要么循環迭代的方式進行讀取,如下所示:
      readValue.read()
    
筆者在上述程序中所讀/寫的都是字符串數據,那么如果是二進制流呢?那就需要使用字節流的方式進行讀取,如下所示:
      #讀取目標數據源的二進制數據流
readValue=open("d:/test.txt","rw")
#向目標數據源寫入二進制數據流
writeValue=open("d:/test2.txt","w")
    
其實讀/寫二進制數據在Python中很簡單,不像在Java中多得讓人眼花繚亂的I/O組件數都數不過來,更不用談記住了, 反觀Python就一個open()函數,其內部指定一個目標數據源地址和操作方式就可以了 。假設我們想實現一個文件復制粘貼的程序,除了使用Python提供的內置函數外,還可以利用手動的方式進行實現,如下所示:
      #文件復制操作
def copy_method(file_path, save_path):
	if not isinstance(file_path,(str)):
		print("只支持所傳遞的參數為字符串")
	else:
		startTime=time.time()
		with open(file_path,"rb") as read_value:
			context = read_value.read()
			print("數據全部讀入完畢,數據大小為->" + str(len(context)/1024) + "KB")
		with open(save_path,"wb") as write_value:
			write_value.write(context)
			print("數據寫入完成...")
			print("耗時->" + str((time.time() - startTime) * 1000) + "ms")
#"E:\\迅雷下載\\move.rmvb", "d:\\move.rmvb"
#copy_method("d:/fengtong.rar", "d:\\fengtong2.rar");

#E:\\迅雷下載\\move.rmvb
#文件復制操作2(適合大文件的讀寫)
def copy_method2(file_path, save_path):
	if not isinstance(file_path,(str)):
		print("只支持所傳遞的參數為字符串")
	else:
		try:
			startTime=time.time()
			write_value = open(save_path,"wb")
			for read_value in open(file_path,"rb"):
				write_value.write(read_value)
			print("數據寫入完成...")
			print("耗時->" + str((time.time() - startTime) * 1000) + "ms")
		finally:
			if write_value:
				write_value.close()
    
上述程序示例中,筆者使用了2種方式實現文件的復制粘貼操作,第一種方式其實適用于文件容量不大的情況,而第二種方式則適用于大文件的情況。如果是讀寫大文件,采用for line in open的方式無疑是最高效的,Python內部自建有 buffer緩沖區機制 ,不至于 一次性讀爆內存 。因此希望大家記住,如果有大文件操作的I/O操作時for line in open的方式必須優先。接下來筆者再演示一個程序,加深大家對I/O技術的掌握和理解,如下所示:
      import os
def findFile(path):
    #列出當前目錄下的所有文件及文件夾
    files = os.listdir(path)
    for file in files:
        if os.path.isfile(file):
            print(file)
        else:
            os.chdir(os.path.abspath(file))
            findFile(os.getcwd())
            cwd=os.getcwd()
            parent=""
            for i in range(len(cwd.split("\\")) - 1):
                parent+=cwd.split("\\")[i] + "\\"
            #切換到上一級目錄
            os.chdir(parent)
filePath="D:\\test"
os.chdir(filePath)
findFile(filePath)
    
?
相信大家都已經注意到了,I/O資源在消費完成之后,必須將其關閉,如果不關閉或者忘記關閉,就會長期 霸占 系統內部資源,極大程度上 系統的 源分 配。就像Java的內存管理一樣,開發人員夢寐以求的就是希望有一天再也無需關注 繁瑣 的資源管理(資源創建、資源就緒、資源回收)。值得慶幸的是Python提供有類似Java7一樣的自動資源管理機制(with open as value)。

?

九、線程操作

其實筆者寫道這里,已經有頂乏力了,為了避免爛尾,筆者就不長篇大論了(今天最后一天上班,木有心情寫了)。簡單來說,多線程指的就是并發,當然并發跟并行的概念還是要區分下,并發是構建于單CPU上,而并行是構建于多CPU上的并發執行。因為我們知道多線程并不是真正意義上的多任務同時執行,而是CPU會不停的做任務切換,交叉運行,看起來貌似是一起執行(CPU切換平率快),但其實不是這樣,只有并行才是真正意義上的多任務同時執行。

?

在Python中定義和使用線程很簡單,Python的API提供了2個模塊:thread和threading,threading對thread模塊進行了封裝。絕大多數情況下,我們只需要使用threading這個模塊即可。啟動一個線程就是把一個函數傳入并創建Thread實例,然后調用start()開始執行即可,如下所示:

      def run():
    for i in range(10):
        print(i)
thread1=threading.Thread(target=run,name="線程A")
thread1.start()
#主線程繼續執行
print("........")
    

?

既然談到線程,不得不提及的還有鎖機制,因為在并發環境下,多線程同時對一個資源進行操作,會造成非線程安全問題,因此Python也提供有鎖機制,如下所示:

      #獲取鎖
value="資源"
lock=threading.Lock()
def run():
    try:
        lock.acquire()
        for i in range(10):
            print(threading.current_thread().name,value)
    finally:
         lock.release()
thread1=threading.Thread(target=run,name="線程A")
thread1.start()
thread2=threading.Thread(target=run,name="線程B")
thread2.start()
    

?

上述程序示例中,多個線程持有同一把鎖,只有當前一個前程使用完并釋放鎖,隊列中的其他線程才能夠正常的訪問同一個資源,以此避免非線程安全問題。當然值得注意的,在Python中,鎖的釋放并非是自動的,而是需要開發人員手動顯式的執行release()函數進行釋放,所以大家千萬要記得使用完之后 一定要記得解鎖 ,否則其他線程就會一直阻塞。

?

在并發場景下,使用鎖可以有效的避免線程安全問題,但是這也同時造成了另外一個問題的出現,那就容易造成 線程死鎖 ,如下所示:

      #encoding=gbk
import threading,time
resourceA="資源A"
resourceB="資源B"
#獲取鎖
lockA=threading.Lock()
lockB=threading.Lock()
def run1():
    try:
        lockA.acquire()
        print("%s成功鎖住"%threading.current_thread().name,resourceA)
        print("%s準備鎖住"%threading.current_thread().name,resourceB)
        time.sleep(1)
        lockB.acquire()
        print("%s成功鎖住"%threading.current_thread().name,resourceB)
    finally:
        lockB.release()
        lockA.release()

def run2():
    try:
        lockB.acquire()
        print("%s成功鎖住"%threading.current_thread().name,resourceB)
        print("%s準備鎖住"%threading.current_thread().name,resourceA)
        lockA.acquire()
        print("%s成功鎖住"%threading.current_thread().name,resourceA)
    finally:
        lockA.release()
        lockB.release()
thread1=threading.Thread(target=run1,name="線程A")
thread1.start()
thread2=threading.Thread(target=run2,name="線程B")
thread2.start()
    

?

簡單來說,就是A線程鎖住A資源的時候,試圖獲取B鎖,但是B線程已經搶先一步獲取到B鎖,這個時候A線程就必須等待,而B線程試圖獲取A鎖時,發現A鎖已經被A線程獲取了,因此雙方都在等待,這樣一來就造成了永久等待,也就是線程死鎖。

?

本章內容到此結束,由于時間倉庫,本文或許有很多不盡人意的地方,希望各位能夠理解和體諒。最后祝愿大家,在新的一年事事順心,萬事如意,羊年行大運。

筆者帶你剖析Python3.x


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 日韩欧美一级大片 | 亚洲人网站 | 免费一级特黄3大片视频 | 99爱在线视频这里只有精品 | 国产精品久久久久久久午夜 | 国产成人综合在线 | 国产成人精品久久二区二区 | 久草在线综合 | 日本高清在线观看视频www | 99久久免费视频在线观看 | 精品国产一区二区三区久久久 | 日本高清色视频在线观看免费 | 99免费观看视频 | 欧美日韩国产在线播放 | 日本黄色大片免费 | 国产精品99久久久久久www | 欧洲视频在线观看 | 精品一二区 | 成人午夜毛片在线看 | 国产午夜精品理论片影院 | 久热香蕉精品视频在线播放 | 婷婷久久五月天 | 成熟人妻AV无码专区A片 | 国内精品视频区在线2021 | 欧美高清视频一区 | 亚洲区欧美中文字幕久久 | 精品国产精品三级精品av网址 | 九九精品视频在线观看九九 | 亚洲日本在线天堂无码 | 99草在线 | 丁香六月婷婷在线 | 一区二区三区四区在线观看视频 | 福利影院在线看 | 日韩精品久久久久 | 99久热国产精品视频尤物不卡 | 久久网精品视频 | 九九九九精品视频在线播放 | 成人在线播放 | 九九久久看少妇高潮A片特黄 | 精品人妻无码一区二区三区手机板 | 97av|