文件的基本操作
操作文件的步驟
在計算機中要操作文件的套路非常固定贝淤,一共包含三個步驟:
- 打開文件播聪;
- 讀离陶、寫文件:讀是指將文件內(nèi)容讀入內(nèi)存招刨;寫將內(nèi)存內(nèi)容寫入文件沉眶;
- 關(guān)閉文件谎倔。
操作文件的函數(shù)/方法
在Python中要擔(dān)任文件需要記住1個函數(shù)和3個方法片习,如下所示:
序號 | 函數(shù)/方法 | 說明 |
---|---|---|
01 | open | 打開文件藕咏,并返回文件操作對象 |
02 | read | 將文件內(nèi)容讀取到內(nèi)存 |
03 | write | 將指定內(nèi)容寫入文件 |
04 | close | 關(guān)閉文件 |
其中open
函數(shù)負責(zé)打開文件,并返回文件對象卦碾,而read/write/close
這三個方法都需要通過文件對象
來調(diào)用起宽。
read方法——讀取文件
-
open
函數(shù)的第一個參數(shù)是要打開的文件(文件名是區(qū)分大小寫的)坯沪,如果文件存在腐晾,返回文件操作對象藻糖,如果文件不存在樱拴,會拋出異常晶乔。 -
read
文件可以一次性讀入并返回文件的所有內(nèi)容正罢。 -
close
方法負責(zé)關(guān)閉文件翻具。如果忘記關(guān)閉文件裆泳,會造成系統(tǒng)資源消耗晾虑,而且會影響到后續(xù)對文件的訪問帜篇。因此笙隙,當(dāng)我們open()
文件后竟痰,就在最后面輸入close()
坏快,對應(yīng)起來莽鸿,再寫中間部分祥得,這樣會避免忘記關(guān)閉文件乒疏。
需要注意的是怕吴,方法執(zhí)行后械哟,會把文件指針移動到文件的末尾暇咆。
現(xiàn)在來看一個案例爸业,我們新建一個README.txt
文件扯旷,如下所示:
hello python!
hello world!
在同一個目錄下新建一個python文件钧忽,命名為hm_01_讀取文件.py
耸黑,如下所示:
# 1. 打開文件
file = open("README")
# 2. 讀取文件內(nèi)容
text = file.read()
print(text)
# 3. 關(guān)閉文件
file.close()
運行結(jié)果如下所示:
hello python!
hello world!
文件指針
文件指針會標(biāo)記從哪個位置開始讀取數(shù)據(jù)大刊,第一次打開文件時缺菌,通常文件指針會指向文件的開始位置耿战,如下所示:
當(dāng)執(zhí)行了read
方法后昆箕,文件指標(biāo)會移動到讀取內(nèi)容的末尾,默認情況下會移動到文件末尾薯嗤,如下所示:
因此镜粤,當(dāng)我們執(zhí)行了一次read
方法后肉渴,讀取了所有內(nèi)容同规,那么再次調(diào)用read
方法券勺,就無法獲取內(nèi)容关炼,因此此時文件指標(biāo)已經(jīng)移到了文件的末尾∪宸鳎現(xiàn)在我們來驗證一下社痛,還是改造原來的代碼:
# 1. 打開文件
file = open("README.txt")
# 2. 讀取文件內(nèi)容
text = file.read()
print(text)
print("-" * 50)
text = file.read()
print(text)
# 3. 關(guān)閉文件
file.close()
運行結(jié)果如下所示:
Hello, python!
Hello, world!
--------------------------------------------------
從結(jié)果中我們可以發(fā)現(xiàn)褥影,第二次調(diào)用read
方法后凡怎,沒有內(nèi)容讀取。我們還可以看一下讀取文件內(nèi)容的長度寨典,如下所示:
# 1. 打開文件
file = open("README.txt")
# 2. 讀取文件內(nèi)容
text = file.read()
print(text)
print(len(text)) #輸出讀取文件長度
print("-" * 50)
text = file.read()
print(text)
print(len(text))
# 3. 關(guān)閉文件
file.close()
運行結(jié)果如下所示:
Hello, python!
Hello, world!
29
--------------------------------------------------
0
從結(jié)果也可以發(fā)現(xiàn)耸成,第二次讀取的長度是0井氢。
打開文件的方式
open
在默認的情況下是以只讀的方式打開文件花竞,并且返回文件對象约急,語法如下所示:
f = open("文件名", "訪問方式")
模式 | 描述 |
---|---|
r | 以只讀方式打開文件厌蔽。文件的指針將會放在文件的開頭奴饮。這是默認模式拐云。 |
rb | 以二進制格式打開一個文件用于只讀叉瘩。文件指針將會放在文件的開頭薇缅。 |
r+ | 打開一個文件用于讀寫泳桦。文件指針將會放在文件的開頭灸撰。 |
rb+ | 以二進制格式打開一個文件用于讀寫完疫。文件指針將會放在文件的開頭壳鹤。 |
w | 打開一個文件只用于寫入芳誓。如果該文件已存在則將其覆蓋锹淌。如果該文件不存在葛圃,創(chuàng)建新文件。 |
wb | 以二進制格式打開一個文件只用于寫入厘唾。如果該文件已存在則將其覆蓋抚垃。如果該文件不存在趟大,創(chuàng)建新文件逊朽。 |
w+ | 打開一個文件用于讀寫叽讳。如果該文件已存在則將其覆蓋邑狸。如果該文件不存在单雾,創(chuàng)建新文件硅堆。 |
wb+ | 以二進制格式打開一個文件用于讀寫硬萍。如果該文件已存在則將其覆蓋朴乖。如果該文件不存在,創(chuàng)建新文件袁勺。 |
a | 打開一個文件用于追加期丰。如果該文件已存在,文件指針將會放在文件的結(jié)尾埠通。也就是說逛犹,新的內(nèi)容將會被寫入到已有內(nèi)容之后虽画。如果該文件不存在渗柿,創(chuàng)建新文件進行寫入灸拍。 |
ab | 以二進制格式打開一個文件用于追加混槐。如果該文件已存在声登,文件指針將會放在文件的結(jié)尾件舵。也就是說,新的內(nèi)容將會被寫入到已有內(nèi)容之后合武。如果該文件不存在盟庞,創(chuàng)建新文件進行寫入什猖。 |
a+ | 打開一個文件用于讀寫。如果該文件已存在荤傲,文件指針將會放在文件的結(jié)尾。文件打開時會是追加模式俊嗽。如果該文件不存在绍豁,創(chuàng)建新文件用于讀寫。 |
ab+ | 以二進制格式打開一個文件用于追加芬位。如果該文件已存在昧碉,文件指針將會放在文件的結(jié)尾四康。如果該文件不存在,創(chuàng)建新文件用于讀寫哎垦。 |
寫入文件
現(xiàn)在我們向README.txt
文件中寫入HELLO
撼泛,如下所示:
# 1. 打開文件
file = open("README.txt", "w")
# 2. 寫入文件
file.write("HELLO")
# 3. 關(guān)閉文件
file.close()
查看一下README.txt
文件,我們使用了w
參數(shù)來寫入文件潘酗,如果原文件中有內(nèi)容仔夺,那么就會覆蓋,如果沒有這個文件惰蜜,就新建。
現(xiàn)在我們來看一下參數(shù)a
受神,這個參數(shù)的功能在于以追加的方式寫入文件抛猖,如下所示:
# 1. 打開文件
file = open("README.txt", "a")
# 2. 寫入文件
file.write("123HELLO")
# 3. 關(guān)閉文件
file.close()
現(xiàn)在我們打開文件README.txt
,結(jié)果為HELLO123HELLO
鼻听。如果分別在參數(shù)r,w,a
的后面添加上+
號财著,即r+, w+, a+
,那么就會以讀寫的方式打開文件撑碴,這會造成頻繁地移動文件指標(biāo)撑教,影響文件的讀寫效率驮履,在開發(fā)中倒戏,更多的是采用只讀或只寫的方式來操作文件矫夷。
按行讀取文件內(nèi)容
read
方法會默認把文件的所有內(nèi)容一次性讀取到內(nèi)存忧陪,如果文件太大,對內(nèi)存的占用會非常嚴(yán)重。此時我們可以使用readline
方法沥匈。
readline方法
readline
方法可以一次讀取一行內(nèi)容,方法執(zhí)行后,會把文件指針移動到下一行,準(zhǔn)備再次讀取椅棺。因此我們在讀取大文件時的代碼通常是如下所示:
file = open("README.txt")
while True:
text = file.readline()
# 判斷是否讀取到內(nèi)容
if not text:
break
print(text)
file.close()
結(jié)果運行如下所示:
Hello1
Hello2
Hello3
文件讀寫案例——復(fù)制文件
在這個案例中丐巫,使用代碼的方式來實現(xiàn)文件的復(fù)制過程赡茸。如果我們要復(fù)制的源文件是一個小文件,那么我們就可以使用read
方法直接把文件的內(nèi)容全部讀取下來,再寫入到另外一個文件中,如下所示:
# 1. 打開文件
file_read = open("README.txt")
file_write = open("README[復(fù)制]", "w")
# 2. 讀纵柿、寫
text = file_read.read()
file_write.write(text)
# 3. 關(guān)閉文件
file_read.close()
file_write.close()
現(xiàn)在在同一個目錄下出現(xiàn)了README[復(fù)制].txt
這個文件,里面的內(nèi)容與README.txt
完全相同。
再看一個案例,這個是案例是復(fù)制大文件底挫。
如果要復(fù)制大文件湿痢,就不能使用read
方法臀规,因為這會對內(nèi)存造成很大的壓力,因此可以使用readline
方法。
現(xiàn)在我們在源文件README.txt
中輸入以下內(nèi)容:
Hello1
Hello2
Hello345
運行復(fù)制大文件的代碼鸯屿,如下所示:
# 1. 打開文件
file_read = open("README.txt")
file_write = open("README[復(fù)制]", "w")
# 2. 讀桑阶、寫
while True:
# 讀取一行內(nèi)容
text = file_read.readline()
# 判斷是否讀取到內(nèi)容
if not text:
break
file_write.write(text)
# 3. 關(guān)閉文件
file_read.close()
file_write.close()
運行后,打開復(fù)制好的文件公壤,README[復(fù)制]
,結(jié)果與源文件一樣。
文件/目錄的常用管理操作
在終端/瀏覽器中可以執(zhí)行常規(guī)的文件/目錄操作稽坤,例如創(chuàng)建顿仇、重命名些阅、刪除、改變路徑、查看目錄內(nèi)容等,在python中拗军,如果要實現(xiàn)上述功能,通常使用os
模塊掌腰。
Python中的目錄操作有這些:
序號 | 方法及描述 |
---|---|
1 | os.access(path, mode):檢驗權(quán)限模式 |
2 | os.chdir(path):改變當(dāng)前工作目錄 |
3 | os.chflags(path, flags):設(shè)置路徑的標(biāo)記為數(shù)字標(biāo)記。 |
4 | os.chmod(path, mode):更改權(quán)限 |
5 | os.chown(path, uid, gid):更改文件所有者 |
6 | os.chroot(path):改變當(dāng)前進程的根目錄 |
7 | os.close(fd):關(guān)閉文件描述符 fd |
8 | os.closerange(fd_low, fd_high):關(guān)閉所有文件描述符邻储,從 fd_low (包含) 到 fd_high (不包含), 錯誤會忽略 |
9 | os.dup(fd):復(fù)制文件描述符 fd |
10 | os.dup2(fd, fd2):將一個文件描述符 fd 復(fù)制到另一個 fd2 |
11 | os.fchdir(fd):通過文件描述符改變當(dāng)前工作目錄 |
12 | os.fchmod(fd, mode):改變一個文件的訪問權(quán)限,該文件由參數(shù)fd指定,參數(shù)mode是Unix下的文件訪問權(quán)限。 |
13 | os.fchown(fd, uid, gid):修改一個文件的所有權(quán)怪瓶,這個函數(shù)修改一個文件的用戶ID和用戶組ID,該文件由文件描述符fd指定杂曲。 |
14 | os.fdatasync(fd):強制將文件寫入磁盤,該文件由文件描述符fd指定怪与,但是不強制更新文件的狀態(tài)信息桅咆。 |
15 | os.fdopen(fd[, mode[, bufsize]]):通過文件描述符 fd 創(chuàng)建一個文件對象梯澜,并返回這個文件對象 |
16 | os.fpathconf(fd, name):返回一個打開的文件的系統(tǒng)配置信息。name為檢索的系統(tǒng)配置的值牵署,它也許是一個定義系統(tǒng)值的字符串,這些名字在很多標(biāo)準(zhǔn)中指定(POSIX.1, Unix 95, Unix 98, 和其它)块仆。 |
17 | os.fstat(fd):返回文件描述符fd的狀態(tài),像stat()拙毫。 |
18 | os.fstatvfs(fd):返回包含文件描述符fd的文件的文件系統(tǒng)的信息衅码,像 statvfs() |
19 | os.fsync(fd):強制將文件描述符為fd的文件寫入硬盤嘹黔。 |
20 | os.ftruncate(fd, length):裁剪文件描述符fd對應(yīng)的文件, 所以它最大不能超過文件大小檩小。 |
21 | os.getcwd():返回當(dāng)前工作目錄 |
22 | os.getcwdu():返回一個當(dāng)前工作目錄的Unicode對象 |
23 | os.isatty(fd):如果文件描述符fd是打開的,同時與tty(-like)設(shè)備相連印衔,則返回true, 否則False玄糟。 |
24 | os.lchflags(path, flags):設(shè)置路徑的標(biāo)記為數(shù)字標(biāo)記箱沦,類似 chflags()童太,但是沒有軟鏈接 |
25 | os.lchmod(path, mode):修改連接文件權(quán)限 |
26 | os.lchown(path, uid, gid):更改文件所有者,類似 chown倔约,但是不追蹤鏈接。 |
27 | os.link(src, dst):創(chuàng)建硬鏈接勾栗,名為參數(shù) dst宿亡,指向參數(shù) src |
28 | os.listdir(path):返回path指定的文件夾包含的文件或文件夾的名字的列表。 |
29 | os.lseek(fd, pos, how):設(shè)置文件描述符 fd當(dāng)前位置為pos, how方式修改: SEEK_SET 或者 0 設(shè)置從文件開始的計算的pos; SEEK_CUR或者 1 則從當(dāng)前位置計算; os.SEEK_END或者2則從文件尾部開始. 在unix来累,Windows中有效 |
30 | os.lstat(path):像stat(),但是沒有軟鏈接 |
31 | os.major(device):從原始的設(shè)備號中提取設(shè)備major號碼 (使用stat中的st_dev或者st_rdev field)面粮。 |
32 | os.makedev(major, minor):以major和minor設(shè)備號組成一個原始設(shè)備號 |
33 | os.makedirs(path[, mode]):遞歸文件夾創(chuàng)建函數(shù)。像mkdir(), 但創(chuàng)建的所有intermediate-level文件夾需要包含子文件夾。 |
34 | os.minor(device):從原始的設(shè)備號中提取設(shè)備minor號碼 (使用stat中的st_dev或者st_rdev field )蓉驹。 |
35 | os.mkdir(path[, mode]):以數(shù)字mode的mode創(chuàng)建一個名為path的文件夾.默認的 mode 是 0777 (八進制)正勒。 |
36 | os.mkfifo(path[, mode]):創(chuàng)建命名管道,mode 為數(shù)字车荔,默認為 0666 (八進制) |
37 | os.mknod(filename[, mode=0600, device]):創(chuàng)建一個名為filename文件系統(tǒng)節(jié)點(文件,設(shè)備特別文件或者命名pipe)炭分。 |
38 | os.open(file, flags[, mode]):打開一個文件,并且設(shè)置需要的打開選項狠裹,mode參數(shù)是可選的 |
39 | os.openpty():打開一個新的偽終端對迄薄。返回 pty 和 tty的文件描述符煮岁。 |
40 | os.pathconf(path, name):返回相關(guān)文件的系統(tǒng)配置信息梗肝。 |
41 | os.pipe():創(chuàng)建一個管道. 返回一對文件描述符(r, w) 分別為讀和寫 |
42 | os.popen(command[, mode[, bufsize]]):從一個 command 打開一個管道 |
43 | os.read(fd, n):從文件描述符 fd 中讀取最多 n 個字節(jié),返回包含讀取字節(jié)的字符串顷级,文件描述符 fd對應(yīng)文件已達到結(jié)尾, 返回一個空字符串。 |
44 | os.readlink(path):返回軟鏈接所指向的文件 |
45 | os.remove(path):刪除路徑為path的文件翼悴。如果path 是一個文件夾思恐,將拋出OSError; 查看下面的rmdir()刪除一個 directory沾谜。 |
46 | os.removedirs(path):遞歸刪除目錄膊毁。 |
47 | os.rename(src, dst):重命名文件或目錄,從 src 到 dst |
48 | os.renames(old, new):遞歸地對目錄進行更名基跑,也可以對文件進行更名婚温。 |
49 | os.rmdir(path):刪除path指定的空目錄,如果目錄非空媳否,則拋出一個OSError異常栅螟。 |
50 | os.stat(path):獲取path指定的路徑的信息,功能等同于C API中的stat()系統(tǒng)調(diào)用篱竭。 |
51 | os.stat_float_times([newvalue]):決定stat_result是否以float對象顯示時間戳 |
52 | os.statvfs(path):獲取指定路徑的文件系統(tǒng)統(tǒng)計信息 |
53 | os.symlink(src, dst):創(chuàng)建一個軟鏈接 |
54 | os.tcgetpgrp(fd):返回與終端fd(一個由os.open()返回的打開的文件描述符)關(guān)聯(lián)的進程組 |
55 | os.tcsetpgrp(fd, pg):設(shè)置與終端fd(一個由os.open()返回的打開的文件描述符)關(guān)聯(lián)的進程組為pg力图。 |
56 | os.tempnam([dir[, prefix]]):Python3 中已刪除。返回唯一的路徑名用于創(chuàng)建臨時文件掺逼。 |
57 | os.tmpfile():Python3 中已刪除吃媒。返回一個打開的模式為(w+b)的文件對象 .這文件對象沒有文件夾入口,沒有文件描述符吕喘,將會自動刪除赘那。 |
58 | os.tmpnam():Python3 中已刪除。為創(chuàng)建一個臨時文件返回一個唯一的路徑 |
59 | os.ttyname(fd):返回一個字符串兽泄,它表示與文件描述符fd 關(guān)聯(lián)的終端設(shè)備。如果fd 沒有與終端設(shè)備關(guān)聯(lián)病梢,則引發(fā)一個異常胃珍。 |
60 | os.unlink(path):刪除文件路徑 |
61 | os.utime(path, times):返回指定的path文件的訪問和修改的時間。 |
62 | os.walk(top[, topdown=True[, onerror=None[, followlinks=False]]]):輸出在文件夾中的文件名通過在樹中游走蜓陌,向上或者向下觅彰。 |
63 | os.write(fd, str):寫入字符串到文件描述符 fd中. 返回實際寫入的字符串長度 |
目錄操作的函數(shù)太多,用到的時候再學(xué)習(xí)钮热,下面只列出幾個簡單的案例:
顯示某文件夾下的所有文件名
代碼如下:
C:\Users\20161111>type practice.py
import os
for filename in os.listdir('d:/Software'):
print(filename)
C:\Users\20161111>python practice.py
office_tools
Professional_tools
ProgramTool
SnapGene 3.2.1 Win
system_enhance
windows_iso
谷歌批量翻譯
創(chuàng)建某個目錄
>>> import os
>>> os.mkdir("d:/Software/test")
>>> exit()
C:\Users\20161111>d:
D:\>cd software
D:\software>dir
Volume in drive D is 新加卷
Volume Serial Number is C0C6-2E4F
Directory of D:\software
2018/05/24 09:33 <DIR> .
2018/05/24 09:33 <DIR> ..
2018/05/08 13:46 <DIR> office_tools
2018/05/21 10:30 <DIR> Professional_tools
2018/05/08 13:46 <DIR> ProgramTool
2017/11/22 20:21 <DIR> SnapGene 3.2.1 Win
2018/05/13 21:38 <DIR> system_enhance
2018/05/24 09:33 <DIR> test # 剛剛創(chuàng)建的文件夾
2018/05/11 00:48 <DIR> windows_iso
2017/11/02 10:52 <DIR> 谷歌批量翻譯
1 File(s) 0 bytes
10 Dir(s) 49,307,074,560 bytes free
刪除某個文件夾
命令rmdir
填抬,如下所示:
>>> import os
>>> os.rmdir('d:/Software/test')
>>> exit()
D:\software>dir
Volume in drive D is 新加卷
Volume Serial Number is C0C6-2E4F
Directory of D:\software
2018/05/25 12:40 <DIR> .
2018/05/25 12:40 <DIR> ..
2018/05/08 13:46 <DIR> office_tools
2018/05/21 10:30 <DIR> Professional_tools
2018/05/08 13:46 <DIR> ProgramTool
2017/11/22 20:21 <DIR> SnapGene 3.2.1 Win
2018/05/13 21:38 <DIR> system_enhance
2018/05/11 00:48 <DIR> windows_iso
2017/11/02 10:52 <DIR> 谷歌批量翻譯
1 File(s) 0 bytes
9 Dir(s) 48,131,309,568 bytes free
把D:\Software\test
這個文件夾刪除了 。
重命名某個文件
如下所示:
D:\netdisk\bioinfo.notes\Python\黑馬教程筆記\13_文件>ipython
Python 3.6.3 |Anaconda, Inc.| (default, Oct 15 2017, 03:27:45) [MSC v.1900 64 bit (AMD64)]
Type 'copyright', 'credits' or 'license' for more information
IPython 6.2.1 -- An enhanced Interactive Python. Type '?' for help.
In [1]: import os
In [2]: os.rename("README.txt","TEST.txt")
In [3]: ls
Volume in drive D is 新加卷
Volume Serial Number is C0C6-2E4F
Directory of D:\netdisk\bioinfo.notes\Python\黑馬教程筆記\13_文件
2019/06/09 16:51 <DIR> .
2019/06/09 16:51 <DIR> ..
2019/06/09 16:46 <DIR> .idea
2019/06/09 15:39 164 hm_01_讀取文件.py
2019/06/09 16:19 229 hm_02_讀取文件后文件指針會改變.py
2019/06/09 16:25 129 hm_03_寫入文件
2019/06/09 16:37 177 hm_04_分行讀取文件.py
2019/06/09 16:41 224 hm_05_復(fù)制文件.py
2019/06/09 16:44 347 hm_06_復(fù)制大文件.py
2019/06/09 16:46 24 README[復(fù)制]
2019/06/09 16:45 24 TEST.txt
8 File(s) 1,318 bytes
3 Dir(s) 52,836,925,440 bytes free
顯示當(dāng)前目錄內(nèi)的所有文件
使用os
模塊下的listdir
命令隧期,如下所示:
In [4]: os.listdir(".")
Out[4]:
['.idea',
'hm_01_讀取文件.py',
'hm_02_讀取文件后文件指針會改變.py',
'hm_03_寫入文件',
'hm_04_分行讀取文件.py',
'hm_05_復(fù)制文件.py',
'hm_06_復(fù)制大文件.py',
'README[復(fù)制]',
'TEST.txt']
判斷文件是目錄還是文件
使用os
模塊中的path.isdir
命令飒责,如下所示:
In [5]: os.path.isdir("TEST.txt")
Out[5]: False
In [6]: os.path.isdir(".idea")
Out[6]: True
eval函數(shù)
eval()
函數(shù)可以接受一個字符串,將其當(dāng)成有效的表達式來求值仆潮,并返回計算結(jié)果宏蛉,來看一下面代碼的運行結(jié)果:
In [1]: # 基本的數(shù)學(xué)計算
In [2]: eval("1 + 1")
Out[2]: 2
In [3]: # 字符串重復(fù)
In [4]: eval("'*' * 10")
Out[4]: '**********'
In [5]: # 將字符串轉(zhuǎn)換成列表
In [6]: type(eval("[1, 2, 3, 4, 5]"))
Out[6]: list
In [7]: # 將字符串轉(zhuǎn)換成字典
In [8]: type(eval("{'name':'xiaoming', 'age':18}"))
Out[8]: dict
eval案例——計算器
需求如下:
- 提示用戶輸入一個加減乘除混合運行;
- 返回過計算結(jié)果性置。
代碼如下所示:
input_str = input("請輸入算術(shù)題: ")
print(eval(input_str))
運行結(jié)果如下所示:
請輸入算術(shù)題: (5+4)*5
45
不要濫用eval
在開發(fā)過程中拾并,不要使用eval
來直接轉(zhuǎn)換input
結(jié)果,現(xiàn)在我們來看一下為什么不要這么做。
我們先來看一下這行代碼(由于本人是在windows環(huán)境下運行的嗅义,因此使用的是dir
命令屏歹,它等于同Linux環(huán)境下的ls
命令,這一點與視頻中的不一樣):
__import__('os').system('dir')
上面的這行代碼等于:
import os
os.system("終端命令")
如果執(zhí)行成功之碗,返回0蝙眶,執(zhí)行失敗,返回錯誤信息〖炭兀現(xiàn)在還看上面的計算器案例械馆,運行后,如果我們輸入的內(nèi)容是__import__('os').system('dir')
武通,我們看一下計算的結(jié)果:
C:\Anaconda3\python.exe D:/netdisk/bioinfo.notes/Python/黑馬教程筆記/13_文件/hm_08_eval計算器.py
請輸入算術(shù)題: __import__('os').system('dir')
驅(qū)動器 D 中的卷是 新加卷
卷的序列號是 C0C6-2E4F
D:\netdisk\bioinfo.notes\Python\黑馬教程筆記\13_文件 的目錄
2019/06/09 19:54 <DIR> .
2019/06/09 19:54 <DIR> ..
2019/06/09 19:57 <DIR> .idea
2019/06/09 15:39 164 hm_01_讀取文件.py
2019/06/09 16:19 229 hm_02_讀取文件后文件指針會改變.py
2019/06/09 16:25 129 hm_03_寫入文件
2019/06/09 16:37 177 hm_04_分行讀取文件.py
2019/06/09 16:41 224 hm_05_復(fù)制文件.py
2019/06/09 16:44 347 hm_06_復(fù)制大文件.py
2019/06/09 19:54 68 hm_08_eval計算器.py
2019/06/09 16:46 24 README[復(fù)制]
2019/06/09 16:45 24 TEST.txt
9 個文件 1,386 字節(jié)
3 個目錄 52,828,184,576 可用字節(jié)
現(xiàn)在我們再換一個命令輸入霹崎,輸入__import__('os').system('cd.>a.txt')
,結(jié)果就會在同一個目錄下創(chuàng)建了一個名為a.txt
的文本文件冶忱。
現(xiàn)在我們再換一個命令尾菇,輸入__import__('os').system('del a.txt')
,此時就會把剛剛創(chuàng)建的那個a.txt
文件刪除囚枪。
此時我們應(yīng)該就明白了派诬,使用eval()
函數(shù)直接轉(zhuǎn)換input
的結(jié)果了,如果用戶使用這個函數(shù)直接調(diào)用os
模塊中的命令链沼,就會執(zhí)行任何終端命令默赂,一旦操作出現(xiàn)失誤,會造成嚴(yán)重的后果括勺。