不管你是待業(yè)還是失業(yè),在這個(gè)被互聯(lián)網(wǎng)圍繞的時(shí)代里,選擇用python計(jì)算,就多了一項(xiàng)技能,還怕找不到工作?,還怕不好找工作?小編就來告訴你這個(gè)專業(yè)的優(yōu)勢(shì)到底體現(xiàn)在哪里:Python 多核并行計(jì)算,Python入門到精通(2):使用Python計(jì)算數(shù)學(xué)算式,python并行計(jì)算(完結(jié)篇):并行方法總結(jié),python計(jì)算360.65+239.2為什么會(huì)出現(xiàn)好多9,python計(jì)算兩個(gè)時(shí)間戳相差多少秒,用Python寫個(gè)計(jì)算器??。
1.Python 多核并行計(jì)算
以前寫點(diǎn)小程序其實(shí)根本不在乎并行,單核跑跑也沒什么問題,而且我的電腦也只有雙核四個(gè)超線程(下面就統(tǒng)稱核好了),覺得去折騰并行沒啥意義(除非在做IO密集型任務(wù))。然后自從用上了32核128GB內(nèi)存,看到 htop 里面一堆空載的核,很自然地就會(huì)想這個(gè)并行必須去折騰一下。后面發(fā)現(xiàn),其實(shí) Python 的并行真的非常簡(jiǎn)單。 vs 自帶的庫(kù)又全又好用,這是我特別喜歡 Python 的原因之一。Python 里面有 和 threading 這兩個(gè)用來實(shí)現(xiàn)并行的庫(kù)。用線程應(yīng)該是很自然的想法,畢竟(直覺上)開銷小,還有共享內(nèi)存的福利,而且在其他語(yǔ)言里面線程用的確實(shí)是非常頻繁。然而,我可以很負(fù)責(zé)任的說,如果你用的是 CPython 實(shí)現(xiàn),那么用了 threading 就等同于和并行計(jì)算說再見了(實(shí)際上,甚至?xí)葐尉€程更慢),除非這是個(gè)IO密集型的任務(wù)。 指的是 python.org 提供的 Python 實(shí)現(xiàn)。是的,Python 是一門語(yǔ)言,它有各種不同的實(shí)現(xiàn),比如 PyPy, Jython, 等等……我們用的最多的就是 CPython,它幾乎就和 Python 畫上了等號(hào)。CPython 的實(shí)現(xiàn)中,使用了 GIL 即全局鎖,來簡(jiǎn)化解釋器的實(shí)現(xiàn),使得解釋器每次只執(zhí)行一個(gè)線程中的字節(jié)碼。也就是說,除非是在等待IO操作,否則 CPython 的多線程就是徹底的謊言!有關(guān) GIL 下面兩個(gè)資料寫的挺好的:Python的GIL是什么鬼,多線程性能究竟如何 the Python .Pool因?yàn)?GIL 的緣故 threading 不能用,那么我們就好好研究研究 。(當(dāng)然,如果你說你不用 CPython,沒有 GIL 的問題,那也是極佳的。)首先介紹一個(gè)簡(jiǎn)單粗暴,非常實(shí)用的工具,就是 .Pool。如果你的任務(wù)能用 ys = map(f, xs) 來解決,大家可能都知道,這樣的形式天生就是最容易并行的,那么在 Python 里面并行計(jì)算這個(gè)任務(wù)真是再簡(jiǎn)單不過了。舉個(gè)例子,把每個(gè)數(shù)都平方:import def f(x): return x * x cores = .cpu_count() pool = .Pool(processes=cores) xs = range(5) # method 1: map print pool.map(f, xs) # prints [0, 1, 4, 9, 16] # method 2: imap for y in pool.imap(f, xs): print y # 0, 1, 4, 9, 16, # method 3: imap_unordered for y in pool.imap_unordered(f, xs): print(y) # may be in any order map 直接返回列表,而 i 開頭的兩個(gè)函數(shù)返回的是迭代器;imap_unordered 返回的是無序的。當(dāng)計(jì)算時(shí)間比較長(zhǎng)的時(shí)候,我們可能想要加上一個(gè)進(jìn)度條,這個(gè)時(shí)候 i 系列的好處就體現(xiàn)出來了。另外,有一個(gè)小技巧,就是輸出 \r 可以使得光標(biāo)回到行首而不換行,這樣就可以制作簡(jiǎn)易的進(jìn)度條了。cnt = 0 for _ in pool.imap_unordered(f, xs): sys.stdout.write('done %d/%d\r' % (cnt, len(xs))) cnt += 1 更復(fù)雜的操作要進(jìn)行更復(fù)雜的操作,可以直接使用 .Process 對(duì)象。要在進(jìn)程間通信可以使用:..Queue同步原語(yǔ)共享變量其中我強(qiáng)烈推薦的就是 Queue,因?yàn)槠鋵?shí)很多場(chǎng)景就是生產(chǎn)者消費(fèi)者模型,這個(gè)時(shí)候用 Queue 就解決問題了。用的方法也很簡(jiǎn)單,現(xiàn)在父進(jìn)程創(chuàng)建 Queue,然后把它當(dāng)做 args 或者 kwargs 傳給 Process 就好了。使用 Theano 或者 等工具時(shí)的注意事項(xiàng)需要注意的是,在 import theano 或者 import 等調(diào)用了 Cuda 的工具的時(shí)候會(huì)產(chǎn)生一些副作用,這些副作用會(huì)原樣拷貝到子進(jìn)程中,然后就發(fā)生錯(cuò)誤,如:could not retrieve CUDA device count: CUDA_ERROR_NOT_ 解決的方法是,保證父進(jìn)程不引入這些工具,而是在子進(jìn)程創(chuàng)建好了以后,讓子進(jìn)程各自引入。如果使用 Process,那就在 target 函數(shù)里面 import。舉個(gè)例子:import def hello(taskq, resultq): import as tf config = tf.() config.gpu_options.allow_growth=True sess = tf.Session(config=config) while True: name = taskq.get() res = sess.run(tf.constant('hello ' + name)) resultq.put(res) if __name__ == '__main__': taskq = .Queue() resultq = .Queue() p = .Process(target=hello, args=(taskq, resultq)) p.start() taskq.put('world') taskq.put('') taskq.close() print(resultq.get()) print(resultq.get()) p.terminate() p.join() 如果使用 Pool,那么可以編寫一個(gè)函數(shù),在這個(gè)函數(shù)里面 import,并且把這個(gè)函數(shù)作為 傳入到 Pool 的構(gòu)造函數(shù)里面。舉個(gè)例子:import def init(): global tf global sess import as tf config = tf.() config.gpu_options.allow_growth=True sess = tf.Session(config=config) def hello(name): return sess.run(tf.constant('hello ' + name)) if __name__ == '__main__': pool = .Pool(processes=2, =init) xs = ['world', '', 'Lequn Chen'] print pool.map(hello, xs) ?首發(fā)于博客 Python 多核并行計(jì)算
2.Python入門到精通(2):使用Python計(jì)算數(shù)學(xué)算式
重點(diǎn)學(xué)習(xí)Python算式表達(dá)式和算術(shù)運(yùn)算符,通過Shell窗口完成簡(jiǎn)單的數(shù)學(xué)運(yùn)算1、 算術(shù)表達(dá)式在Pyhton語(yǔ)言中,數(shù)學(xué)算式中的小數(shù)或整數(shù)稱為數(shù)值,數(shù)學(xué)算式稱為算術(shù)表達(dá)式。算式中的數(shù)值稱為操作數(shù),算式中的運(yùn)算符號(hào)稱為運(yùn)算符。在算術(shù)表達(dá)式中,算式的數(shù)值稱為操作數(shù),算式的運(yùn)算符號(hào)稱為運(yùn)算符。在一些復(fù)雜的運(yùn)算中,簡(jiǎn)單的表達(dá)式可以組合為復(fù)雜的表達(dá)式,其操作數(shù)本身可能就是一個(gè)表達(dá)式。算術(shù)表達(dá)式的計(jì)算結(jié)果為數(shù)值。例如上圖表達(dá)式運(yùn)算符“+”兩邊的操作數(shù)是(12+9)和(20/5),它們本身就是一個(gè)表達(dá)式。2、 算術(shù)運(yùn)算符下面的表格對(duì)算術(shù)表達(dá)式使用到的運(yùn)算符和數(shù)學(xué)算式中的運(yùn)算符號(hào)進(jìn)行了比較,這樣就可以借助數(shù)學(xué)算式的運(yùn)算符號(hào)來理解算術(shù)表達(dá)式的運(yùn)算符。在算術(shù)運(yùn)算符表格中,加減乘除運(yùn)算符已經(jīng)比較熟悉了。下面介紹取模運(yùn)算符“%”、冪運(yùn)算運(yùn)算符“**”和取整除“//”運(yùn)算符。取模運(yùn)算符“%”用于取模運(yùn)算,取模運(yùn)算和數(shù)學(xué)中的取余運(yùn)算是一樣的,運(yùn)算結(jié)果返回兩個(gè)數(shù)值相除后的余數(shù)。上機(jī)操作:首先計(jì)算163除以7,163除以7的商是23余數(shù)是2。然后在IDLE的Shell窗口輸入算術(shù)表達(dá)式“163 % 7”,按下電腦鍵盤的【Enter】鍵,Shell窗口執(zhí)行輸入的算術(shù)表達(dá)式并輸出結(jié)果2?!?5 % 5”的運(yùn)算結(jié)果是多少呢?15除以5的余數(shù)是0。如果兩數(shù)相除的余數(shù)是0,那么這兩個(gè)數(shù)取模運(yùn)算的結(jié)果是多少呢?上機(jī)操作:在Shell窗口輸入“15 % 5”,Shell窗口執(zhí)行算式,并輸出結(jié)果0。冪運(yùn)算符“**”用于數(shù)值的乘方運(yùn)算,乘方運(yùn)算是指一個(gè)數(shù)連續(xù)自乘n次,可以稱為該數(shù)的n次乘方。例如:3個(gè)5連續(xù)自乘,可以稱為3的5次乘方。除0外,任何數(shù)的0次乘方都為1。乘方運(yùn)算的結(jié)果稱為冪,因此乘方運(yùn)算也稱為冪運(yùn)算。冪運(yùn)算符“**”有兩個(gè)操作數(shù),運(yùn)算符左邊的操作數(shù)是乘方的底數(shù),運(yùn)算符右邊的操作數(shù)是乘方的指數(shù)。例如:計(jì)算2的3次方,算術(shù)表達(dá)式可以這么寫“2**3”,2是底數(shù),3是指數(shù)。上機(jī)操作:在Shell窗口輸入了算術(shù)表達(dá)式“2**3”,Shell窗口輸出計(jì)算結(jié)果8。使用冪運(yùn)算符時(shí),運(yùn)算符左側(cè)的數(shù)值是乘方運(yùn)算的底數(shù),運(yùn)算符右側(cè)的數(shù)值是乘方運(yùn)算的指數(shù)。取整除運(yùn)算符“//”用于兩數(shù)除法取商的整數(shù)部分,也就是運(yùn)算結(jié)果返回兩數(shù)相除后商的整數(shù)部分,商的小數(shù)部分及余數(shù)忽略。例如:19除以2的取整除運(yùn)算結(jié)果是9。取整除運(yùn)算符“//”有兩個(gè)操作數(shù),運(yùn)算符左邊的操作數(shù)是被除數(shù),運(yùn)算符右邊的操作數(shù)是除數(shù)。上機(jī)操作:在Shell窗口輸入算術(shù)表達(dá)式“19 // 2”,Shell窗口輸出計(jì)算結(jié)果9。在輸入“//”運(yùn)算符時(shí)要注意和除法運(yùn)算符“/”的區(qū)別,除法運(yùn)算符是一個(gè)“/”符號(hào),取整除是兩個(gè)“//”符號(hào)。了解了算術(shù)運(yùn)算符,做下面的練習(xí)!在上機(jī)練習(xí)前,先介紹一下練習(xí)的操作步驟:(1)首先啟動(dòng)IDLE開發(fā)工具,Shell窗口被打開。(2)在Shell窗口的命令提示符“>>>”的光標(biāo)處輸入算術(shù)表達(dá)式,算術(shù)表達(dá)式輸入完成后,按下電腦鍵盤【Enter】鍵,Shell窗口會(huì)執(zhí)行剛才輸入的算術(shù)表達(dá)式,并在算術(shù)表達(dá)式的下面一行,輸出算術(shù)表達(dá)式的計(jì)算結(jié)果。在Shell窗口輸入上面的算式,每輸入完成一個(gè)算式,就按下電腦鍵盤的【Enter】鍵執(zhí)行該算式。>>> 21+79-3268>>> 28+120*8988>>> (45+16)/4*23350.75>>> 3**327>>> 19 % 61>>> 21 // 63>>>初學(xué)Python的同學(xué)在輸入算術(shù)表達(dá)式時(shí),可能會(huì)在輸入法的中文模式下輸入,如果在中文模式下輸入,可能會(huì)導(dǎo)致算術(shù)表達(dá)式的語(yǔ)法錯(cuò)誤。上面的錯(cuò)誤就是在輸入算式時(shí),在中文模式下輸入了小括號(hào)“(”,Shell窗口會(huì)輸出“語(yǔ)法錯(cuò)誤:標(biāo)識(shí)符中的字符無效”錯(cuò)誤。3、 運(yùn)算符的優(yōu)先級(jí)算術(shù)運(yùn)算符的優(yōu)先級(jí)同四則運(yùn)算的優(yōu)先級(jí)相同,下表給出了算術(shù)運(yùn)算符的優(yōu)先級(jí),表中優(yōu)先級(jí)的數(shù)字越小,優(yōu)先級(jí)越高。優(yōu)先級(jí)的結(jié)合性是指當(dāng)一個(gè)表達(dá)式包含優(yōu)先級(jí)相同的運(yùn)算符時(shí),表達(dá)式是從左到右順序運(yùn)算,還是從右到左順序運(yùn)算。4、 上機(jī)操作請(qǐng)同學(xué)們先用筆算計(jì)算下面的算術(shù)表達(dá)式,然后在用Python驗(yàn)證算術(shù)表達(dá)式的計(jì)算結(jié)果是否正確。(1)0.94*2.6-0.9*2.6(2)3**2//3+(12-5)(3)6/3+10//3**2編程訓(xùn)練營(yíng)APP創(chuàng)新在線學(xué)習(xí)模式,學(xué)習(xí)編程不再半途而廢安卓手機(jī)應(yīng)用商店搜索編程訓(xùn)練營(yíng)下載
3.python并行計(jì)算(完結(jié)篇):并行方法總結(jié)
由于python相當(dāng)易學(xué)易用,現(xiàn)在python也較多地用于有大量的計(jì)算需求的任務(wù)。本文介紹幾個(gè)并行模塊,以及實(shí)現(xiàn)程序并行的入門技術(shù)。本文比較枯燥,主要是為后面上工程實(shí)例做鋪墊。完結(jié)篇對(duì)前期介紹的所有模塊及實(shí)例進(jìn)行總結(jié),比較各并行方法的特點(diǎn)和異同。所有比較都以文字形式呈現(xiàn)了,歡迎指正或完善,做成表格可能效果更好。模塊介紹:愛coding:python并行計(jì)算(上):、模塊愛coding:python并行計(jì)算(上):pathos模塊愛coding:python并行計(jì)算(上):.futures、pp模塊實(shí)例:愛coding:python并行計(jì)算(下):模塊實(shí)例愛coding:python并行計(jì)算(下):pathos模塊實(shí)例愛coding:python并行計(jì)算(下):.futures、pp模塊實(shí)例注:以下模塊、類與其他內(nèi)容相同或接近,不重復(fù)介紹和比較:模塊:與模塊接口基本一致。pathos.pp.pp模塊:實(shí)質(zhì)也即pp模塊,與獨(dú)立的pp模塊完全相同。pathos..Pool():與.Pool()完全相同。pathos..()、pathos.pools.():與pathos..()完全相同。pathos.pp.()、pathos.parallel.()、pathos.parallel.()、pathos.pools.():與pathos.pp.()完全相同。pathos.serial.():實(shí)際是串行(非并行),不參與比較。1、按并行分類(1)阻塞(非并行):非并行方式下,子進(jìn)程串行執(zhí)行(完成一個(gè),然后開始下一個(gè)),實(shí)際不是并行。包括:.Pool(),apply方法pathos..(),pipe方法pathos.pp.(),pipe方法pathos.pp.(),map方法pathos.pp.(),imap方法(2)批次并行:批次并行指一批子進(jìn)程并行執(zhí)行,且直到該批次所有子進(jìn)程完成后,才開始下一批次。包括:.Process() #只能一批一批地添加進(jìn)程,同一批次內(nèi)并行(3)異步:異步執(zhí)行指的是一批子進(jìn)程并行執(zhí)行,且子進(jìn)程完成一個(gè),就新開始一個(gè),而不必等待同一批其他進(jìn)程完成。包括:.Pool(),apply_async方法.Pool(),map方法.Pool(),map_async方法.Pool(),imap方法.Pool(),imap_unordered方法.Pool(),starmap方法.Pool(),starmap_async方法.futures.(),submit方法.futures.(),map方法pathos..(),map方法pathos..(),imap方法pathos..(),uimap方法pathos..(),amap方法pathos..(),apipe方法pp.Server(),submit方法pathos.pp.(),apipe方法pathos.pp.(),amap方法pathos.pp.(),uimap方法2、按傳參分類(1)單個(gè)任務(wù),任務(wù)多參數(shù):.Process().futures.(),submit方法.Pool(),apply方法.Pool(),apply_async方法pathos..(),pipe方法pathos..(),apipe方法pp.Server(),submit方法pathos.pp.(),pipe方法pathos.pp.(),apipe方法(2)多個(gè)任務(wù),任務(wù)單參數(shù):.Pool(),map方法.Pool(),map_async方法.Pool(),imap方法.Pool(),imap_unordered方法(3)多個(gè)任務(wù),任務(wù)多參數(shù):(a)func(iterable[i])形式:iterable的每個(gè)元素(元素本身也是iterable)對(duì)應(yīng)func的多個(gè)參數(shù)。.Pool(),starmap方法.Pool(),starmap_async方法(b)func(iterable1[i], iterable2[i], ...)形式:每個(gè)iterable對(duì)應(yīng)func的一個(gè)參數(shù)。.futures.(),map方法pathos..(),map方法pathos..(),imap方法pathos..(),uimap方法pathos..(),amap方法pathos.pp.(),map方法pathos.pp.(),amap方法pathos.pp.(),imap方法pathos.pp.(),uimap方法3、按返回分類(1)返回任務(wù)返回值.Pool(),apply方法pathos..(),pipe方法pathos.pp.(),pipe方法(2)返回.Pool(),map方法.Pool(),starmap方法pathos..(),map方法pathos.pp.(),map方法(3)返回返回MapResult或?qū)嵗?,通過get方法獲取返回值。需要注意的是:由于每個(gè)實(shí)例對(duì)應(yīng)單個(gè)子進(jìn)程,其get方法本身是阻塞的,因此,在進(jìn)程添加過程中不可包含get方法,而應(yīng)在所有進(jìn)程完成后,再一起調(diào)用get方法。對(duì)于MapResult不存在該問題,因?yàn)樗凶舆M(jìn)程只會(huì)一起返回一個(gè)MapResult實(shí)例。包括:.Pool(),apply_async方法pathos..(),apipe方法pathos.pp.(),apipe方法(4)返回.Pool(),map_async方法.Pool(),starmap_async方法pathos..(),amap方法pathos.pp.(),amap方法(5)返回迭代器或生成器迭代器/生成器對(duì)內(nèi)存的需求會(huì)小得多,但速度比普通方法要慢很多(未驗(yàn)證)。不過,對(duì)于本文的小型任務(wù),看不出差別。(a)按順序:即按任務(wù)添加順利返回。.Pool(),imap方法.futures.(),map方法pathos..(),imap方法pathos.pp.(),imap方法(b)不按順序:實(shí)際按任務(wù)完成順序返回。.Pool(),imap_unordered方法pathos..(),uimap方法pathos.pp.(),uimap方法(6)無直接返回值.Process() #無直接返回值,可通過進(jìn)程間通信的方式返回任務(wù)返回值。.futures.(),submit方法 #future對(duì)象可以通過result方法獲取子進(jìn)程任務(wù)返回值。但該方法是阻塞的,因此,應(yīng)在所有子進(jìn)程完成后再調(diào)用。pp.Server(),submit方法 #Task對(duì)象可調(diào)用(即Task()),調(diào)用可返回任務(wù)返回值。但調(diào)用是阻塞的,因此,應(yīng)在所有子進(jìn)程完成后再調(diào)用。
4.python計(jì)算360.65+239.2為什么會(huì)出現(xiàn)好多9
深層原因是在于計(jì)算機(jī)無法精確表示部分浮點(diǎn)數(shù)時(shí),只能近似表示,因此存在誤差,這是所有編程語(yǔ)言都存在的問題,可深入了解下,這種問題無法徹底解決; 常見的應(yīng)對(duì)辦法是在制定的精度要求下,乘法-》截取-》除法,如 0.1 + 0.2 = 0. (保留1位小數(shù))int(0. *10 ) /10,截取方法也有很多可了解下;
5.python計(jì)算兩個(gè)時(shí)間戳相差多少秒
在Python編程中,使用datetime模塊計(jì)算兩個(gè)時(shí)間的差:>>> import datetime>>> d1=datetime.datetime(2015,7,5)>>> d2=datetime.datetime(2005,7,4)>>>(d1-d2).seconds//結(jié)果86400s# 計(jì)算兩個(gè)時(shí)間的間隔天數(shù)# 注意:輸入月份和天時(shí),不能輸入08,09等,會(huì)被識(shí)別為 8 進(jìn)制而出錯(cuò)!(8進(jìn)制是不超過07的)# 解決辦法:要把月份和天前面的0去掉。
6.用Python寫個(gè)計(jì)算器
我們常見的計(jì)算輔助工具有兩種,一種是古人發(fā)明的算盤,另一種就是我們現(xiàn)代人發(fā)明的計(jì)算器,與算盤相比,計(jì)算器無論是便利性還是計(jì)算速度都是優(yōu)于算盤的,本文我們使用 Python 來實(shí)現(xiàn)一個(gè)簡(jiǎn)易的計(jì)算器。實(shí)現(xiàn)我們幾乎每個(gè)人都用過計(jì)算器,大家對(duì)于計(jì)算器應(yīng)該都是比較熟悉的,計(jì)算器整體也是比較簡(jiǎn)單的,主要包括:顯示器、鍵盤、運(yùn)算的邏輯處理等,計(jì)算器的圖形界面我們使用 tkinter 庫(kù)實(shí)現(xiàn),下面看一下具體實(shí)現(xiàn)過程。首先,我們畫一個(gè)主窗口,代碼實(shí)現(xiàn)如下:# 創(chuàng)建主窗口 tk = tkinter.Tk() # 設(shè)置窗口大小和位置 tk.geometry('300x210+500+200') # 不允許改變窗口大小 tk.resizable(False, False) # 設(shè)置窗口標(biāo)題 tk.title('計(jì)算器')看一下效果:我們接著畫顯示器,代碼實(shí)現(xiàn)如下:# 自動(dòng)刷新字符串變量,可用 set 和 get 方法進(jìn)行傳值和取值 = tkinter.StringVar(tk, '') # 創(chuàng)建單行文本框 = tkinter.Entry(tk, =) # 設(shè)置文本框?yàn)橹蛔x ['state'] = 'readonly' # 設(shè)置文本框坐標(biāo)及寬高 .place(x=20, y=10, width=260, height=30)看一下效果:再接著畫鍵盤,代碼實(shí)現(xiàn)如下:# 按鈕顯示內(nèi)容 bvalue = ['C', '+', '-', '//', '2', '0', '1', '√', '3', '4', '5', '*', '6', '7', '8', '.', '9', '/', '**', '='] index = 0 # 將按鈕進(jìn)行 5x4 放置 for row in range(5): for col in range(4): d = bvalue[index] index += 1 btnDigit = tkinter.Button(tk, text=d, command=lambda x=d: onclick(x)) btnDigit.place(x=20 + col * 70, y=50 + row * 30, width=50, height=20)看一下效果:界面畫完了,我們看一下處理運(yùn)算邏輯的代碼,如下所示:# 點(diǎn)擊事件 def onclick(btn): # 運(yùn)算符 operation = ('+', '-', '*', '/', '**', '//') # 獲取文本框中的內(nèi)容 content = .get() # 如果已有內(nèi)容是以小數(shù)點(diǎn)開頭的,在前面加 0 if content.('.'): content = '0' + content # 字符串可以直接用+來增加字符 # 根據(jù)不同的按鈕作出不同的反應(yīng) if btn in '': # 按下 0-9 在 content 中追加 content += btn elif btn == '.': # 將 content 從 +-*/ 這些字符的地方分割開來 lastPart = re.split(r'\+|-|\*|/', content)[-1] if '.' in lastPart: # 信息提示對(duì)話框 tkinter..showerror('錯(cuò)誤', '重復(fù)出現(xiàn)的小數(shù)點(diǎn)') return else: content += btn elif btn == 'C': # 清除文本框 content = '' elif btn == '=': try: # 對(duì)輸入的表達(dá)式求值 content = str(eval(content)) except: tkinter..showerror('錯(cuò)誤', '表達(dá)式有誤') return elif btn in operation: if content.endswith(operation): tkinter..showerror('錯(cuò)誤', '不允許存在連續(xù)運(yùn)算符') return content += btn elif btn == '√': # 從 . 處分割存入 n,n 是一個(gè)列表 n = content.split('.') # 如果列表中所有的都是數(shù)字,就是為了檢查表達(dá)式是不是正確的 if all(map(lambda x: x.isdigit(), n)): content = eval(content) ** 0.5 else: tkinter..showerror('錯(cuò)誤', '表達(dá)式錯(cuò)誤') return # 將結(jié)果顯示到文本框中 .set(content)整體實(shí)現(xiàn)完了之后,我們來演示一下,看一下效果:是不是有內(nèi)味了。打包為了更加方便的使用,我們可以將 Python 代碼打包成 exe 文件,打包我們使用 ,安裝用 pip install 命令即可。打包時(shí)我們使用 --onefile -- counter.py 命令即可,此時(shí)打包生成的文件是使用的默認(rèn)圖標(biāo),如果我們想指定自己的圖標(biāo)可以添加參數(shù) --icon="xxx\xxx.ico",打包生成的文件在 dist 目錄,如下圖所示:此時(shí),我們直接運(yùn)行 exe 文件就行了。用 Python 寫個(gè)計(jì)算器本文非首發(fā)于個(gè)人號(hào)
就拿大數(shù)據(jù)說話,優(yōu)勢(shì)一目了然,從事IT行業(yè),打開IT行業(yè)的新大門,找到適合自己的培訓(xùn)機(jī)構(gòu),進(jìn)行專業(yè)和系統(tǒng)的學(xué)習(xí)。