程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式師世界 >> 編程語言 >  >> 更多編程語言 >> Python

Python 快速入門(第3版)11-13章 讀書筆記

編輯:Python

《Python 快速入門(第3版)》娜奧米·賽德

 11.1.2 命令行參數

argvtest.py內容如下

import sys
def main():
print(sys.argv)
main()

命令行參數會以字符串列表的形式存入sys.argv中

# python argvtest.py arg1 arg2 arg3
['argvtest.py', 'arg1', 'arg2', 'arg3']

11.1.3 腳本輸入/輸出的重定向

一般來說,命令行 
​​python script.py arg1 arg2 arg3 < infile > outfile​​
的運行效果是,把input或sys.stdin的所有操作都定向為來自infile,把print或sys.stdout的所有操作都定向到outfile。這種效果如同是將sys.stdin設為只讀模式('r')的infile,將sys.stdout設為只寫('w')模式的outfile。以下命令效果一致,
注:把">"改為“>>”將使輸出結果追加至outfile末尾,而不是會覆蓋掉輸出文件。

例,replace.py內容如下

import sys
def main():
contents = sys.stdin.read()
sys.stdout.write(contents.replace(sys.argv[1],sys.argv[2]))
main()

infile.txt內容如下

one two zero
zero three four
a s dfgh aaaaa

執行 python3 replace.py zero 0 <infile.txt> outfile.txt,outfile.txt內容如下

one two 0
0 three four
a s dfgh aaaaa

繼續執行 python3 replace.py a A <infile.txt>> outfile.txt

# cat outfile.txt
one two 0
0 three four
a s dfgh aaaaa
one two zero
zero three four
A s dfgh AAAAA

結合管道符,如下命令會把 "a"替換為"A", "one"替換為"1"輸出到outfile.txt

[[email protected] ~]# python3 replace.py a A <infile.txt | python3 replace.py one 1 > outfile.txt
[[email protected] ~]# cat outfile.txt
1 two zero
zero three four
A s dfgh AAAAA
[[email protected] ~]#

11.1.4 argparse模塊

argparse模塊_wy_hhxx

11.1.5 fileinput模塊的使用

fileinput模塊_wy_hhxx

11.2 讓腳本在UNIX下直接運行

在腳本文件的第一行加入以下命令,並將文件屬性修改正確,即chmod +x <filename>
​​#!/usr/bin/env python​​

我的測試環境使用的python3且非默認,所以需要使用 ​​#!/usr/bin/env python​​3

[[email protected] ~]# ls -l test1.py
-rwxr-xr-x 1 root root 333 Jul 3 12:01 test1.py
[[email protected] ~]# ./test1.py
in decorate function, decorating myfunction
Executing myfunction
hello
[[email protected] ~]#

也可以使用python3的執行路徑

[[email protected] ~]# whereis python3
python3: /usr/local/python3 /usr/local/python3/bin/python3.9 /usr/local/python3/bin/python3.9-config /usr/local/python3/bin/python3
[[email protected] ~]#

嘗試在腳本開頭加上如下任意一行,都可以直接執行
#!/usr/bin/env python​​3
#!/usr/local/python3/bin/python3.9
#!/usr/local/python3/bin/python3

11.5 程序和模塊

將腳本代碼和模塊結合在一起是很簡單的,也就是在主控函數之外加上以下條件測試:

​​if __name__ == '__main__':
    main()
    else:
        # 本模塊的初始化代碼​​


如果被作為腳本調用,運行時的當前模塊名稱將會是__main__,於是會調用主控函數main。如果條件測試已導入交互式會話或其他模塊中,則模塊名稱將會是其文件名。

12.2 路徑和路徑名

12.2.2 當前工作目錄

os模塊
os.curdir  #返回'.'
os.getcwd()  #返回當前工作路徑 pwd
os.chdir('somepath')  #cd xxx
os.listdir(os.curdir)  #ls

>>> import os
>>> os.curdir
'.'
>>>
>>> os.getcwd()
'/root'
>>>
>>> os.chdir('/opt')
>>> os.getcwd()
'/opt'
>>> os.listdir(os.curdir)
['rh', 'containerd', 'cni']
>>>
>>> os.listdir('/opt')
['rh', 'containerd', 'cni']
>>>

12.2.3 用pathlib模塊訪問目錄

>>> import pathlib
>>> pathlib.Path()
PosixPath('.')
>>> cur_path = pathlib.Path()
>>> cur_path.cwd()
PosixPath('/opt')
>>>

pathlib不提供像os.chdir()那樣改變當前目錄的函數,但可以通過創建path對象來新建文件夾

12.2.4 路徑名的處理

os.path.join函數將參數解釋為一系列的目錄名或文件名
os.path.split函數將返回由兩個元素組成的元組,將路徑拆分為文件名(路徑尾部的單個文件或目錄名稱,basename)和其余部分
os.path.dirname函數只返回路徑部分
os.path.basename函數只返回路徑中的文件名
os.path.splitext函數可以處理以句點標識的文件擴展名

>>> import os
>>> os.path.join('bin','utils','disktools')
'bin/utils/disktools'
>>>
>>> os.path.split('/bin/utils/disktools/')
('/bin/utils/disktools', '')
>>> os.path.split('/bin/utils/disktools')
('/bin/utils', 'disktools')
>>>
>>> os.path.dirname('/bin/utils/disktools/')
'/bin/utils/disktools'
>>> os.path.dirname('/bin/utils/disktools')
'/bin/utils'
>>> os.path.basename('/bin/utils/disktools')
'disktools'
>>>
>>> os.path.splitext('/bin/utils/disktools/pic.jpg')
('/bin/utils/disktools/pic', '.jpg')
>>>

12.2.5 用pathlib處理路徑名

>>> from pathlib import Path
>>> cur_path = Path()
>>> print(cur_path.joinpath('bin','utils','disktools'))
bin/utils/disktools
>>>
>>>
>>> a_path = Path('bin','utils','disktools')
>>> a_path
PosixPath('bin/utils/disktools')
>>>
>>> a_path.parts
('bin', 'utils', 'disktools')
>>>
>>> a_path.name
'disktools'
>>> a_path.parent
PosixPath('bin/utils')
>>> a_path.suffix
''
>>>
>>> b_path = Path('/bin/utils/disktools/pic.jpg')
>>>
>>> b_path.suffix
'.jpg'
>>>

os.path和pathlib.Path比較

os.pathpathlib.Pathos.path.join('bin','utils','disktools')
返回str

a_path = Path('bin','utils','disktools')

返回<class 'pathlib.PosixPath'>

os.path.split('/bin/utils/disktools/')

返回tuple

a_path.parts

返回tuple

os.path.dirname('/bin/utils/disktools/')

返回str

a_path.parent
返回<class 'pathlib.PosixPath'>

os.path.basename('/bin/utils/disktools')

返回str

a_path.name

返回str

os.path.splitext('/bin/utils/disktools/pic.jpg')

返回str

a_path.suffix

返回str

12.2.6 常用變量和函數

最基本的常量就是os.curdir和os.pardir,分別定義了操作系統用於表示目錄和父目錄的路徑符號。

os.name大多數Windows版本都被識別為'nt'
在運行OS X的Mac機器上,以及Linux/UNIX系統中,返回值將為posix

>>> os.curdir
'.'
>>> os.pardir
'..'
>>> os.name
'posix'
>>>

12.3 獲取文件信息

以下函數接收路徑信息,返回True/False
os.path.exists 
os.path.isfile
os.path.isdir
os.path.islink
os.path.ismount
os.path.isabs 是否為絕對路徑

os.path.samefile(path1, path2) 當且僅當參數中的兩個路徑指向同一個文件時,才會返回True

os.path.getsize(path) 返回路徑名大小
os.path.getmtime(path) 最後修改時間
os.path.getatime(path) 最後訪問時間

12.4 文件系統的其他操作
(1)os.listdir 獲取目錄中的文件列表
說明:Python在os.listdir返回的文件列表中,不包含os.curdir和os.pardir標識符

在glob模塊中有個glob函數能夠擴展路徑名中的Linux/UNIX  shell風格的通配符和字符序列,返回當前工作目錄中匹配的文件。“*”將匹配任意字符序列,“?”匹配任意單個字符,字符序列(如[h,H]或[0-9])則會匹配序列中的任意單個字符:

>>> import glob
>>> glob.glob("*.cfg")
['original-ks.cfg', 'anaconda-ks.cfg']
>>> glob.glob("sole?.tst")
['sole1.tst', 'sole2.tst']
>>>

(2)用os.rename可以重命名/移動文件或目錄
(3)用os.remove可以刪除文件
         用os.rmdir可以刪除空目錄
         如果要刪除非空目錄,請使用shutil.rmtree函數,它能以遞歸方式刪除目錄樹中的所有文件

補充:shutil模塊中的copytree函數,能夠遞歸地復制目錄及其子目錄下的所有文件,文件的權限和狀態信息(即訪問/修改時間)都予以保留。

>>> os.rmdir('testdir/1/2')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
OSError: [Errno 39] Directory not empty: 'testdir/1/2'
>>>
>>> import shutil
>>> shutil.rmtree('testdir')
>>>

(4)用os.makedirs或os.mkdir創建目錄
說明:os.makedirs會連同必要的中間目錄一起創建,但os.mkdir不會

pathlib提供的其它文件操作
(1)以上提到的大多數操作,Path對象都具備同樣功能的方法,但還是有一些區別。iterdir方法類似於os.path.listdir函數,但返回的是路徑迭代器而不是字符串列表

>>> new_path = Path('/opt')
>>> new_path.iterdir()
<generator object Path.iterdir at 0x7f520bf3e820>
>>> list(new_path.iterdir())
[PosixPath('/opt/rh'), PosixPath('/opt/containerd'), PosixPath('/opt/cni')]
>>>

(2)用Path對象的rename方法,可以重命名(移動)文件和目錄

>>> new_path = Path('mymath_update.py')
>>> old_path = Path('mymath.py')
>>> old_path.rename(new_path)
PosixPath('mymath_update.py')
>>>
>>> cur_path = Path('./')
>>> list(cur_path.iterdir())
[PosixPath('addlinenum.py'), PosixPath('drop2hash.py'), PosixPath('linestatistics.py'), PosixPath('replace.py'), PosixPath('mymath_update.py')]
>>>

(3)要移除或刪除數據文件,請使用unlink方法,不能用unlink方法來刪除目錄
         要刪除目錄請使用rmdir方法,它只刪除空目錄

>>> new_path
PosixPath('mymath_update.py')
>>> new_path.unlink()
>>> list(cur_path.iterdir())
[PosixPath('addlinenum.py'), PosixPath('drop2hash.py'), PosixPath('linestatistics.py'), PosixPath('replace.py')]
>>>

(4)要通過path對象創建目錄,請使用path對象的mkdir方法。如果調用時帶了parents=True參數,mkdir方法就會創建必要的中間目錄。否則,就會在中間目錄不存在時引發FileNotFoundError

>>> new_path = Path('/root/newdir1/newdir2/')
>>> new_path.mkdir()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/python3/lib/python3.9/pathlib.py", line 1313, in mkdir
self._accessor.mkdir(self, mode)
FileNotFoundError: [Errno 2] No such file or directory: '/root/newdir1/newdir2'
>>>
>>> new_path.mkdir(parents=True)
[[email protected] ~]# ls -ld /root/newdir1/newdir2/
drwxr-xr-x 2 root root 6 Jul 3 17:43 /root/newdir1/newdir2/
[[email protected] ~]#

 

文件系統屬性值和函數匯總

 

pathlib部分屬性和方法

 

13.1 打開文件及file對象

open不會讀取文件中的內容,而是返回一個file對象,可用於訪問被打開的文件。file對象將會對文件及讀寫位置進行跟蹤記錄。
第一次調用readline將返回file對象的第一行,包括第一個換行符在內。

13.2 關閉文件

>>> file_object = open("myfile", 'r')
>>> line = file_object.readline()
>>> file_object.close()

利用上下文管理器和with關鍵字:

>>> with open("myfile", 'r') as file_object:
... line = file_object.readline()
... print(line)
...
2022-7-3
>>>

13.4 讀寫文本及二進制數據的函數

readline將從file對象中讀取並返回一行數據,包括行尾的換行符。如果文件中沒有數據可讀了,readline將返回空字符串

【例1】使用readline計算文本文件中的文本行數

file_object = open("myfile",'r')
count = 0
while file_object.readline() != "":
count = count + 1
print(count)
file_object.close()

readlines方法將讀取文件中的所有行,並作為字符串列表返回(每行尾部的換行符仍然保留)

【例2】使用readline計算文本文件中的文本行數

file_object = open("myfile",'r')
print(len(file_object.readlines()))
file_object.close()

注意:如果要對一個大型文件統計行數,readlines方法可能會導致計算機內存不足,因為它會一次性將整個文件讀入內存。

與readline和readlines方法對應的寫入方法是write和writelines。
注意,不存在writeline方法。

write方法將寫入一個字符串,如果字符串中包含了換行符,則可以一次寫入多行。
write方法在把參數字符串寫入完畢後,不會再輸出換行符。

writelines方法的參數是字符串列表,將字符串逐個寫入file對象,但不會寫入換行符。如果列表中的字符串以換行符結尾,則它們將被寫成多行,否則在文件中就會緊緊連在一起。

>>> myfile = open("myfilewrite",'w')
>>> myfile.write('Hello')
5
>>> myfile.write('Hello')
5
>>> myfile.write('Hi\nHi\nHi')
8
>>> myfile.writelines(['One','Two','Three'])
>>> myfile.writelines(['1\n','Two\n','Three'])
>>>
-------------------------------------------------
[[email protected] pydir]# ls -l myfilewrite
-rw-r--r-- 1 root root 0 Jul 3 19:24 myfilewrite
[[email protected] pydir]#
-------------------------------------------------
>>> myfile.close()
>>>
-------------------------------------------------
[[email protected] pydir]#
[[email protected] pydir]# ls -l myfilewrite
-rw-r--r-- 1 root root 40 Jul 3 19:26 myfilewrite
[[email protected] pydir]# cat myfilewrite
HelloHelloHi
Hi
HiOneTwoThree1
Two
Three[[email protected] pydir]#

不過writelines是readlines的精確逆操作,可以對readlines返回的列表直接使用writelines,將寫入一個與readlines讀入的文件完全相同的文件。
假設有一個文本文件myfile.txt,以下代碼將為其創建名為myfilecopy.txt的精確副本:

>>> input_file = open("myfile.txt", 'r')
>>> lines = input_file.readlines()
>>> input_file.close()
>>> output = open("myfilecopy.txt", 'w')
>>> output.writelines(lines)
>>> output.close()
>>>

13.5 用pathlib讀寫文件

用Path對象來讀寫文本文件不需要執行打開或關閉操作。
限制:無法用Path的方法追加數據,因為其寫入操作會把現有數據全部替換掉。

>>> from pathlib import Path
>>> p_text = Path('my_text_file')
>>> p_text.write_text('Some contents.')
14
>>> p_text.read_text()
'Some contents.'
>>>


  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式師世界 All Rights Reserved