1.文件
1.1 從文件中讀取數據
文本文件中可存儲的數據量多的難以置信:天氣數據、交通數據、社會經濟數據、文學作品等。每當需要分析或修改存儲在文件中的信息時,讀取文件都很有用,對數據分析應用程序來說尤其如此。
要使用文本文件中的信息。首先需要將信息讀取到內存中。爲此,你可以一次性讀取文件的全部內容,也可以以每次一行的方式逐步讀取。
1.1.1 讀取整個文件
要讀取文件,需要一個包含幾行文本的文件。首先假如我們擁有以下文件:
song_digits.txt
8.3254585665
1565649795
1596324785
將文件保存到你要使用的程序目錄。
下面的程序打開並讀取這個文件,再將其內容顯示到屏幕上:
方法一:
with open('song_digits.txt') as f :
contents = f.read( )
print(contents)
方法二:
f = open('song_digits.txt')
contents = f.read( )
print(contents)
f.close
我們擁有兩種讀取文件的方法,第一種方法與第二種方法的區別是,第一種方法不用執行f.close( )這行代碼。
在這兩個程序中,第一行代碼都做了大量的工作。我們先來看看函數open( )。要以任何方式使用文件——哪怕僅僅是打印其內容,都得先打開文件,這樣才能訪問他。函數open( )只接受一個參數:要打開的文件名稱。python在當前執行的py文件所在的目錄中查找指定的文件,或者在open( )函數中寫入絕對路徑,找到讀取文件。函數open( )返回一個表示文件的對象;python將這個對象存儲在我們後面將要使用的變量中。
關鍵字with在不再需要訪問文件時將他自動關閉。在這個程序中,注意我們調用了open(),但沒有調用close( );你也可以調用open( )和 close( )來打開關閉文件,但這樣做時,如果程序存在bug,導致close語句未執行,文件將不會關閉。這看似微不足道,但未妥善關閉文件可能會導致數據丟失或受損。如果在程序中過早的調用close(),你會發現使用文件時他已經關閉,這會導致更多的錯誤。並非任何情況下都能輕鬆的確定關閉確定關閉文件的恰當時機,但是通過with結構,我們可以讓python確定:你只管打開文件在需要時使用它,python會在合適的時候自動將其關閉。
有了表示song_digits.txt的對象後,我們使用方法read( ),讀取文件的全部內容,並將其作爲長長的字符串儲存在變量contents中,這樣通過打印contents這個值就可將這個文本文件的全部內容顯示出來。
我們在輸出文件時,唯一不同的地方是末尾多了一個空行。位和會多出一個空行?因爲read()在到達文件末尾時會返回一個空字符串,而將這個空字符串顯示出來就是一個空行,要刪除多與的空行我們可以在print語句中使用rstrip( ):
print(contents.rstrip())
這樣輸出內容就與源是文件內容相同了。
1.1.2 文件路徑
我們在執行一個打開一個文件時,如果你只寫入了一個文件名,而剛好你要打開的文件不再你要操作的目錄中,這樣你打開的文件,就不正確。所以我們可以在open( )函數中寫入絕對路徑,例如linux’或者OS X中:
with open('/home/kiosk/text_file/filename.txt') as f:
或者
file_path = '/home/kiosk/text_file/filename.txt'
with open(file_path) as f:
在Window中使用:
with open('C:\Users\ehmatthes\other_files\text_file\filename.txt') as f:
或者
file_path = 'C:\Users\ehmatthes\other_files\text_file\filename.txt'
with open(file_path) as f:
1.1.3 逐行讀取
讀取文件時,常常需要檢查其中的每一行。要以每次以行的方式檢查文件,可對文件對象使用for循環:
file_read.py
filename = 'song_digits.txt'
with open(filename) as f:
for line in f:
print(line)
這時候我們發現打印每一行的時,發現空白行更多了,這是因爲在每一行的末尾都有一個看不見的換行符,而print語句也會加哈桑一個換行符,因此每行末尾都有兩個換行符:一個來自文件,另一個來自print語句。要消除這些多與的空白行,可在語句中使用rstrip():
filename = 'song_digits.txt'
with open(filename) as f:
for line in f:
print(line.rstrip())
這樣輸出的內容就一致了。
1.1.4創建一個包含文件個行內容的列表
使用with關鍵字時,open()返回的對象只在with代碼塊內可用。如果要在with代碼塊外訪問文件內容,可再with代碼塊內將文件的個行儲存在一個列表中,再在with代碼塊外使用這個列表。
filename = 'song_digits.txt'
with open(filename) as f:
line = f.readlines()
for i in line:
print(line.read.rstrip())
readlines( )從文件中讀取每一行,並將其儲存在一個列表中;接下來,該列表被儲存在變量line中;在with代碼塊外,我們依然可以使用這個變量。
然後我們使用for循環來打印line中的個行。由於line中的每個與元素對應文件中的每一行。因此輸出與文件內容完全一致。
1.1.5 使用文件的內容
將文件讀取到內存後,就可以以任何方式使用這些數據了。首先,我們將建立一個字符串,它包含文件中儲存的所有數字,且沒有任何空格:
filename = 'song_digits.txt'
with open(filename) as f:
line = f.readlines()
song_string = ''
for i in line:
song_string +=i.rstrip()
print(song_string)
print(len(song_string))
就像前一個示例一樣,我們首先打開一個文件,將所有行都存儲在一個列表中。我們創建了一個song_string變量用來存儲文件中的數值。接下來我們使用循環將各行都加入到song_string中,並刪除每行的換行符。
但是在song_string中包含每行左邊的空格,爲刪除這些空格我們可以使用strip而不是rstrip。
filename = 'song_digits.txt'
with open(filename) as f:
line = f.readlines()
song_string = ''
for i in line:
song_string +=i.strip()
print(song_string)
print(len(song_string))
這樣我們就得到了字符串,和字符串的長度。
1.2 寫入文件
1.2.1 寫入空文件
要將文本寫入到文件中,你調用open時需要提供另一個參數,告訴python你要寫入的打開文件。爲明白其中的工作原理,我們呢將一條簡單的信息存儲到文件中而不是打印到屏幕上:
write_message.py
filename = 'songwrite.txt'
whith open(filename,w) as f:
f.write("I love python!!!")
在這個示例中,調用open()時用了兩個參數。第一個參數是要打開的文件的名稱;第二個實參‘w’告訴python。我們要以寫入模式打開這個文件。打開文件時可指定以下幾種模式:
r
r(readonly)默認參數,只能讀,不能寫,讀取文件不存在 會報錯。
將文件以r模式打開。我們可以得到
首先我們在/tmp下查看不存在的passwd文件。
w
寫文件,文件存在的時候,會清空文件的內容並寫入新的文件內容,文件不存在的時候,會創建新的文件並寫入內容
我們可以看到以w模式打開的文件,可以寫但是不能讀。
我們也可以應用w進行清空更改內容。
a
寫文件(write only)
寫:不會清空文件內容,會在文件末尾追加
寫:文件不存在的時候,不會報錯,會創建新文件並寫入內容
沒有文件,建立文件,寫入內容。
w+
r/w
文件不存在 不報錯 會創建新文件並寫入
會清空文件
可讀可寫可建立。
文件清空寫入,可讀可寫會清空。
r+
r/w
不會清空文件
文件不存在 報錯
文件不存在報錯不會建立。
我們用普通用戶的身份打開的pycharm,所以沒有權限修改此文件。
寫入成功,要有權限。
r+的寫入是將原文件進行修改,寫指針與讀指針使用同一個指針,所以寫指針運行到第三個指針處,第三個位置,所以我們以讀到最後一個位置的內容g。
a+
r/w
不會清空文件,文件不存在建立文件,不會報錯。
這裏爲什麼會有兩個空行,這是因爲,文件中讀指針在最後一位,有一個換行符,print又自帶換行功能所以會有一個空行,所以會輸出兩個換行符。
追加書寫,依舊含有兩個空行。
1.3 讀取非純文本文件
如果讀取的是 圖片 音頻 視頻(非純文本文件)
需要通過二進制的方式讀取和寫入
-讀取純文本文件
r r+ w w+ a a+ == rt rt+ wt wt+ at at+
-讀取二進制文件
rb rb+ wb wb+ ab ab+
我們可以以變量的形式,將要附值的文件保存,這樣就可以直接進行復制。
1.4 指針的變化
默認情況下讀取文件的內容 小的文件:直接用read讀取即可
如果是一個大文件(文件大小>=內存) readline()
我們使用readline可以逐行讀取文件,我們第二行爲空行,所以我們得到是‘ ’,b代表是以二進制的形式打開。
按字節,讀取
將文章的所有的行作爲列表的元素輸出:
seek():指針的移動
第一個參數:偏移量 >0:向後移動 <0:向前移動
第二個參數:
0:移動到文件開頭
1:當前位置
2:移動到文件的末尾
1.5 練習題
生成100個MAC地址並寫入文件中,MAC地址前6位(16進制)爲01-AF-3B
01-AF-3B-xx-xx-xx
-xx
01-AF-3B-xx
-xx
01-AF-3B-xx-xx
-xx
01-AF-3B-xx-xx-xx
- 生成一個大文件ips.txt,要求1200行,每行隨機爲172.25.254.0/24段的ip;
- 讀取ips.txt文件統計這個文件中ip出現頻率排前10的ip;
2.裝飾器
2.1 裝飾器的定義
裝飾器:
把一個函數當作參數傳遞給另一個函數,返回一個替代版的函數
本質上就是一個返回函數的函數
“在不改變原函數的基礎上 給函數增加功能”
語法糖:
函數再包裝
輸出的是內存中的地址。
2.2函數計時器
我們使用 @functools.wraps(func)是爲了讓函數在輸出時,認清函數到底是什麼。
2.4 打印日誌
創建裝飾器, 要求如下:
- 創建add_log裝飾器, 被裝飾的函數打印日誌信息;
- 日誌格式爲: [字符串時間] 函數名: xxx, 運行時間:xxx,運行返回值結果:xxx
2.5 函數的封裝與拆裝
解釋器在一句一句的讀這段代碼,首先發現兩個裝飾器,將其保存在內存中,然後發現了被兩層語法糖包裝的函數,首先裝飾裏層的b,這時b函數中出現了一個輸出b,然後裝飾外層的a,這時a函數中出現了一個輸出a,然後出現了使用函數,我們開始拆裝,拆裝後先拆外層的a,a要使用函數時,發現還有一層b所以我們再拆b,最終才能使用。
2.6用戶登錄
[‘root’,‘admin’,‘redhat’]
id id+vip
多個裝飾器的應用場景:
會採用多個裝飾器先驗證是否登陸成功 再驗證權限是否足夠
我們使用inspect.getcallargs是爲了??? inspect.getcallargs的用法。
2.7 isinstance函數
編寫裝飾器required_ints, 條件如下:
1). 確保函數接收到的每一個參數都是整數;
2). 如果參數不是整形數, 打印 TypeError:參數必須爲整形
2. 升級版(有參數的裝飾器)
編寫裝飾器required_types, 條件如下:
1). 當裝飾器爲@required_types(int,float)確保函數接收到的每一個參數都是int或者float類型;
2). 當裝飾器爲@required_types(list)確保函數接收到的每一個參數都是list類型;
3). 當裝飾器爲@required_types(str,int)確保函數接收到的每一個參數都是str或者int類型;
4). 如果參數不滿足條件, 打印 TypeError:參數必須爲xxxx類型
3.os模塊
3.1 系統信息
在os模塊中我們確定linux爲posix,所以我們可以將posix轉化爲linux。
我們使用輸出os.uname()可以查看所有的操作系統信息,或者使用sysname輸出系統名稱,使用nodename輸出
3.2 環境變量
輸出所有的環境變量
輸出指定的環境變量
3.3 判斷是否是絕對路徑
就算指定的文件不存在,依然可以說,他是絕對路徑。
3.5 生成絕對路徑
3.5 獲取目錄名和文件名
3.6 創建目錄
3.7創建文件 刪除文件
3.8 文件重命名
3.9判斷文件或目錄是否存在
3.10 分離後綴名和文件名
3.11 將目錄名和文件名分離
3.12 練習
- 在當前目錄新建目錄img, 裏面包含多個文件,文件名各不相同(X4G5.png)
- 將當前img目錄所有以.png結尾的後綴名改爲.jpg
3.12 時間模塊輔助
利用time.time()方法,我們可以計算兩個時間點
之間的時間間隔,但是有些時候我們想要得到/etc/group
文件的最後a/c/m的時間,對應的年月日這些信息
並保存再文件date.txt文件中
4.時間模塊
4.1 時間表示的幾種類型
1.時間戳
2.字符串時間
3.元組類型的時間
4.2常用的時間轉換