【干货】eval函数用法解释及对开发者的便利讲解
個人見解,有選擇閱讀,歡迎評論指正
Python中,默認有個函數(shù)名為eval。這個函數(shù)在諸多像我一樣的菜雞圈子里,是很少用的。我也一直以為這個沒什么特別大的作用。直到今天,我在讀一個源代碼的時候,突然意識到這個函數(shù)的用途。
由于水平有限,如果認為不對的地方,歡迎在評論區(qū)指出。
在我進行概括總結(jié)之前,容我先展示一下,我以前用這個函數(shù)實現(xiàn)代碼,作為例子。
第一個代碼: 計算器(快速實現(xiàn))
下面是我用pyqt實現(xiàn)的計算器代碼(可能需要在這個源代碼文件目錄下,放一個特定圖片文件,換上特定的名字然后作為圖片。如果想要直接運行,也可以把這個地方給注釋掉)
用Python3
import sys from PyQt5.QtWidgets import QApplication, QWidget, QToolTip, QLineEdit, QMessageBox, QDesktopWidget, QTextEdit from PyQt5.QtGui import QIcon, QFont from PyQt5.QtCore import QCoreApplicationclass Calculater(QWidget):def __init__(self):super().__init__()self.setUI()def setUI(self):QToolTip.setFont(QFont('SansSerif', 10))Font = QFont('SansSerif', 18)self.resize(500, 400)self.move(100, 100)self.setWindowTitle("Calculater")self.setWindowIcon(QIcon('./1.jpg'))self.center()self.line = QLineEdit(self)self.line.resize(480, 80)self.line.move(10, 10)self.line.setFont(Font)self.Text = QTextEdit(self)self.Text.resize(480, 280)self.Text.move(10, 110)self.Text.setFont(Font)self.Text.setText(str(0))self.line.textChanged.connect(self.calculate)self.show()def calculate(self):s = self.line.text()if len(s) == 0:self.Text.setText(str(0))return Falses = s.replace('^', '**') # 使得能夠接受^這樣的用法try:ans = eval(s)except:return Falseelse:self.Text.setText(str(ans))def center(self):qr = self.frameGeometry()cp = QDesktopWidget().availableGeometry().center()qr.moveCenter(cp)self.move(qr.topLeft())if __name__ == '__main__':app = QApplication(sys.argv)ex = Calculater()sys.exit(app.exec_())在上面的代碼中,是實現(xiàn)我輸入一個表達式的過程中就自動顯示結(jié)果。
至于部分的解析,大家可以點擊這里查看。
但是我們這里主要是想要看在,這個類中的一個函數(shù)。
def calculate(self):s = self.line.text()if len(s) == 0:self.Text.setText(str(0))return Falses = s.replace('^', '**') # 使得能夠接受^這樣的用法try:ans = eval(s) # 使用了evalexcept:return Falseelse:self.Text.setText(str(ans))看到了沒有,在上面,通過使用這個快速實現(xiàn)了這個功能。想想自己以前用c++實現(xiàn)的時候,還有用一個大概50+行的簡單算法實現(xiàn)。但是通過這個eval函數(shù),在這別壓縮到只用一行。(當然啦,這個就涉及到Python這個函數(shù)的C代碼實現(xiàn)的!)
不過在開發(fā)上確實變簡單了很多。
第二個程序,Tk加上偏函數(shù),實現(xiàn)簡單實用。
我之前說到,我在看一段代碼,就是值得這個源代碼。
代碼在這,用python2
from functools import partial as pto from Tkinter import Tk, Button, X from tkMessageBox import showinfo, showwarning, showerrorWARN = 'warn' CRIT = 'crit' REGU = 'regu'SIGNS = {'do not enter': CRIT,'railroad crossing': REGU,'55\n speed limit': REGU,'wrong way': CRIT,'merging traffic': WARN,'one way': REGU, }critCB = lambda: showerror('Error', 'Error Button Pressed!') warnCB = lambda: showwarning('Warning', 'Warning Button Pressed!') infoCB = lambda: showinfo('Info', 'Info Button Pressed!')top = Tk() top.title('Road Signs') Button(top, text='Quit', command=top.quit, bg='red', fg='white').pack()MyButton = pto(Button, top) CritButton = pto(MyButton, command=critCB, bg='white', fg='red') WarnButton = pto(MyButton, command=warnCB, bg='goldenrod1') ReguButton = pto(MyButton, command=infoCB, bg='white')for eachSign in SIGNS:signType = SIGNS[eachSign]cmd = '%sButton(text=%r%s).pack(fill=X, expand=True)' % (signType.title(), eachSign, '.upper()' if signType == CRIT else '.title()')eval(cmd)top.mainloop()注意到,在這個代碼的靠后面的幾行代碼,有這樣的一個片段。
for eachSign in SIGNS:signType = SIGNS[eachSign]cmd = '%sButton(text=%r%s).pack(fill=X, expand=True)' % (signType.title(), eachSign, '.upper()' if signType == CRIT else '.title()')eval(cmd) # 使用eval而在這里,我們使用了eval函數(shù)來輸入代碼。
可能大家第一個看到這代碼,會想:這個玩意什么鬼??
哈哈哈這個確實很搞笑。我之前在Linux上用C++做過類似的功能都一下子楞到了。
這里,eval開始執(zhí)行代碼了。
我們這么說起。相信,用python的朋友,肯定都是用過命令行交互模式?;蛘哒f,那種交互模式才是一般非大程序開發(fā)使用的常態(tài)。(除非學習這個的人是程序員出身的….一般都會偏好命令行交互(有時候,會發(fā)現(xiàn)命令行交互確實實用,方便。))
- 經(jīng)過觀察,還有查資料。我們可以理解這個eval。就是在之前的代碼執(zhí)行的基礎(chǔ)上,開始執(zhí)行一個新的代碼。
可能大部分人的第一反映,都是會覺得我在這胡扯。如果是這個功能有什么用呢?我直接手寫這個語句不就好了?為什么還要通過eval這個函數(shù)來調(diào)用呢?
這里就涉及到了一個非常大膽的猜想
- 想我們編程過程中,經(jīng)常會遇到要編寫大量的重復(fù),或者是相近的代碼。這里,從代碼出現(xiàn)開始,教授們,大神們,給我們的推薦就是諸如,增加代碼的復(fù)用性這樣的策略。
- 具體的實現(xiàn)呢,就會映射出一大批的技術(shù)手段。比如:
- 函數(shù)式編程:通過將復(fù)用的手段變成函數(shù)封裝起來。然后每次調(diào)用的時候,就只需要改特定的參數(shù)了。
- 面向?qū)ο缶幊?#xff1a;封裝成一個個類。這里不僅是增加了諸多方法(如,函數(shù))的復(fù)用性。同時由于封裝為一個整體,很大程度上提高了數(shù)據(jù)的復(fù)用性。(這里比如:我要設(shè)置一個關(guān)于人的變量,我可能就需要身高,性別等很多很多的信息。這每個特征都需要設(shè)置為一個int,或者string類型。這樣你開法的程序沒過多久就會把所有的你可能會想到的變量名全都使用完,或者是大幅度地增加變量名的長度。這里想到我的大學同學,一個學醫(yī)學的,他們上課一個單詞有高達 40(左右)個英語字母,這樣的情況肯定是會加大開發(fā)的難度的。)
- 面向?qū)ο缶幊?#xff08;多態(tài),繼承):這個也大幅度增加了復(fù)用性。這個主要體現(xiàn)在使用構(gòu)造類上的輕松。同時,python這個語言就是一個非常好的通過這個技術(shù)開發(fā)出來的語言。(所有函數(shù),變量,類都基于object這個類)。。
這里,在python中引入的eval作用就很可怕了。以前雖然能解決很多復(fù)用問題,但是有一類的問題沒辦法解決。
比如:
將下面的傳轉(zhuǎn)換成整數(shù)
這里只有三個,我們會想到的方法有,寫三句話
A = int(A_str) B = int(B_str) C = int(C_str)這還是由于python內(nèi)植入了int這個函數(shù)的原因。要是沒有,就需要自己再實現(xiàn)相關(guān)的代碼了??偟膩碚f,這里會特別復(fù)雜。
其實,就算只有三行類似這樣的代碼。我們敲起來都覺得很煩。這么重復(fù)的東西,為什么要我們自己手動敲代碼?計算機才是最擅長干這種事情的呀??這種思想一直在程序員的圈子很受歡迎~
但,要是這里變成了100這個的變量呢?你會怎么處理?
這里,你可能會說,那我就不這樣設(shè)置變量咯~然后封裝成一個數(shù)組之類的東西,這樣不就很好了么?
確實,其他很多語言都沒有這個函數(shù)都還是能用,肯定是有這樣的理由的。
但是,有必要強調(diào)的是,這樣就會大大降低可讀性質(zhì)。(我們無法通過變量很快的得知對應(yīng)的意思, 雖然大多數(shù)條件下,這個不影響,但是很多時候這個很有必要!)
比如我那使用的代碼(雖然也可以使用手打
但是那樣就會特別麻煩。
Python作為一門簡潔的語言,怎么會讓自己有這樣的漏洞呢?(能解決的問題,最好就提前解決。
因為Python最受歡迎的一點,就是使用起來特別方便,特別容易上手~這點既然存在,那它就必須要去解決掉。
所以,就有了這個函數(shù)。
這個函數(shù)最大的功能!
就是,通過這函數(shù),實現(xiàn)了程序員內(nèi)心深處最想要的工具,就是自動打碼!
對,這個功能特別夸張,在這種基礎(chǔ)下,很大程度上縮短了代碼量。
因為,很多代碼由于有類似的特征。就通過控制string的方式來進行控制代碼,然后這樣,就可以通過一個模板,讓程序自動生成一系列相關(guān)的代碼。
比如我用的第二代碼!
總結(jié)
以上是生活随笔為你收集整理的【干货】eval函数用法解释及对开发者的便利讲解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [解析]多线程加锁Lock调用pytho
- 下一篇: 【干货】Dask快速搭建分布式集群(大数