一、文本文件讀寫
- 直接讀入
file = open('pima-indians-diabetes.txt', 'r')
while True:
line = file.readline()
print(line)
if not line:
break
用open函數(shù)進行讀寫,第一個參數(shù)為文件名,第二個參數(shù)可以是‘r’(read),‘w’(write),‘a(chǎn)’(append)。'r'為只讀模式,‘w’用寫的模式進行打開,寫入時會覆蓋原來的內(nèi)容,‘a(chǎn)’在后面添加內(nèi)容。
讀文件有3種方法:
- read()將文本文件所有行讀到一個字符串中。
- readline()是一行一行的讀
- readlines()是將文本文件中所有行讀到一個list中,文本文件每一行是list的一個元素。 優(yōu)點:readline()可以在讀行過程中跳過特定行。
- 文件迭代器,用for循環(huán)的方法
file2 = open("output.txt","w")
for line in open("test.txt"):
#這里可以進行邏輯處理
file2.write('"'+line[:s]+'"'+",")
- 文件上下文管理器
#打開文件
#用with..open自帶關(guān)閉文本的功能
with open('somefile.txt', 'r') as f:
data = f.read()
# loop整個文檔
with open('somefile.txt', 'r') as f:
for line in f:
# 處理每一行
# 寫入文本
with open('somefile.txt', 'w') as f:
f.write(text1)
f.write(text2)
...
# 把要打印的line寫入文件中
with open('somefile.txt', 'w') as f:
print(line1, file=f)
print(line2, file=f)
二、二進制文件讀寫
Python默認讀取的都是文本文件。要是想要讀取二進制文件,需要把剛剛的'r'改成'rb'。
f = open('EDC.jpg', 'rb'
任何非標準的文本文件(對于Py2來說,標準是ASCII,對于Py3來說,標準是unicode),你就需要用二進制讀入這個文件,然后再用 .decode('...')的方法來解碼這個二進制文件:
f = open('DegangGuo.txt', 'rb')
# 讀入郭德綱老師的作文, 但是郭老師用的是參合著錯別字的繁體編碼,假設(shè)叫個"DeyunCode"
# 那么你讀入以后,就需要解碼它
u = f.read().decode('DeyunCode')
三、文件目錄的操作
- 基本操作
用Python內(nèi)置的os模塊直接調(diào)用操作系統(tǒng)提供的接口函數(shù):
import os
os.name
# 'posix'
這里是通過OS告訴我們 我的操作系統(tǒng)的名字。 如果是posix,說明系統(tǒng)是#nix族,如果是nt,就是Windows。我們可以調(diào)用uname()來看看具體信息。
注:import xxx,默認情況下python解析器會搜索當(dāng)前目錄、已安裝的內(nèi)置模塊和第三方模塊,搜索路徑存放在sys模塊的path中。對于模塊和自己寫的腳本不在同一個目錄下,在腳本開頭加sys.path.append('xxx'):
import sys
sys.path.append(’引用模塊的地址')
- 環(huán)境變量
在操作系統(tǒng)中定義的環(huán)境變量,全部保存在os.environ這個dict中,可以直接查看.
os.environ
- 操作文件與目錄
查看、創(chuàng)建和刪除目錄可以這么調(diào)用:
# 當(dāng)前目錄的絕對路徑
os.path.abspath('.')
# 比如這里返回:'/Users/EDC'
# 在某個目錄下創(chuàng)建一個新目錄,
# 首先把新目錄的完整路徑表示出來:
os.path.join('/Users/EDC', 'Pictures') #詳細用法,文末鏈接
# 這里你得到的是一個字符串,代表了新的文件夾是這個位置:/Users/EDC/Pictures
# 自己也可以拼起來,但是怕不同操作系統(tǒng)下的區(qū)分符問題,最好是用OS接口
# 但是你還并沒有創(chuàng)建任何的文件
# 需要用mkdir創(chuàng)建:
os.mkdir('/Users/EDC/Pictures/')
# 同理,刪除一個文件夾
os.rmdir('/Users/EDC/Pictures/')
同樣的道理,要拆分路徑時,也不要直接去拆字符串,而要通過os.path.split()函數(shù),這樣可以把一個路徑拆分為兩部分,后一部分總是最后級別的目錄或文件名:
os.path.split('/Users/EDC/Pictures/AJiao.avi')
# ('/Users/EDC/Pictures/', 'AJiao.avi')
或者靠os.path.splitext()得到文件擴展名:
os.path.splitext('/Users/EDC/Pictures/AJiao.avi')
# ('/Users/EDC/Pictures/AJiao', '.avi')
文件重命名:
os.rename('JAV-001.avi', '學(xué)習(xí)資料')
刪除文件:
os.remove('學(xué)習(xí)資料')
python 中的復(fù)制文件操作不在os模塊中,需要導(dǎo)入第三方包進行復(fù)制:
import shutil
shutil.copyfile('/path/to/file', '/path/to/other/file')
四、序列化和反序列化
程序運行的過程中,所有變量都是在內(nèi)存中操作的,當(dāng)程序一旦執(zhí)行完畢,結(jié)束退出后,變量占有的內(nèi)存就被操作系統(tǒng)回收了。 因此我們需要將某些數(shù)據(jù)持久化存儲到磁盤中,下次運行的時候從磁盤中讀取相關(guān)數(shù)據(jù)。
我們將變量從內(nèi)存中變成可以存儲或傳輸?shù)倪^程稱之為序列化,在Python中叫做pickling,在其它語言中也稱之為 serialization、marshaling、flattening等等,說的都是一個意思。 反之,則為反序列化,稱之為unpickling,把變量內(nèi)容從序列化的對象重新讀取到內(nèi)存中。
import pickle
# 此處定義一個dict字典對象
d = dict(name='思聰', age=29, score=80)
str = pickle.dumps(d) # 調(diào)用pickle的dumps函數(shù)進行序列化處理
print(str)
# 定義和創(chuàng)建一個file文件對象,設(shè)定模式為wb
f = open('dump.txt', 'wb')
# 將內(nèi)容序列化寫入到file文件中
pickle.dump(d, f)
f.close() # 最后關(guān)閉掉文件資源
剛剛的搞成的“序列化”的碼,轉(zhuǎn)成python看得懂的object
import pickle
# 從之前序列化的dump.txt文件里邊讀取內(nèi)容
f = open('dump.txt', 'rb') # 設(shè)定文件選項模式為rb
d = pickle.load(f) # 調(diào)用load做反序列處理過程
f.close() # 關(guān)閉文件資源
print(d)
print('name is %s' % d['name'])
稍微注意一下,python2和python3里面的pickle不一樣。為了保證2,3的和諧,你可以用這個方法來保證你import正確:
try:
import cPickle as pickle
except ImportError:
import pickle
五、Lambda表達式
Lambda函數(shù)的語法只包含一個語句,如下:
lambda [arg1 [,arg2,.....argn]]:expression
arg 為參數(shù)列表;expression為簡單的邏輯;
例如相加函數(shù):
sum = lambda arg1, arg2: arg1 + arg2
sum(10, 20)
# 輸出30
除了Lambda本身,Python還提供了其他幾個輔助工具。
- reduce
Python中的reduce內(nèi)建函數(shù)是一個二元操作函數(shù),他用來將一個數(shù)據(jù)集合(列表,元組等)中的所有數(shù)據(jù)進行如下操作:傳給reduce中的函數(shù)func() (必須是一個二元操作函數(shù))先對集合中的第1,2個數(shù)據(jù)進行操作,得到的結(jié)果再與第三個數(shù)據(jù)用func()函數(shù)運算,最后得到一個結(jié)果。顧名思義,reduce就是要把一個list給縮成一個值。所以必須用二元操作函數(shù)。
from functools import reduce
l = [1,2,3,4,5]
print(reduce(lambda x,y: x+y, l))
# 這里代表著,把list中的值,一個個放進lamda的x,y中
# 輸出15
# 如果你給出一個初始值,可以放在list后面
print(reduce(lambda x,y: x+y, l, 10))
# 這樣,x開始的時候被賦值為10,然后依次
# 輸出25
- map
map函數(shù)應(yīng)用于每一個可迭代的項,返回的是一個結(jié)果map。如果有其他的可迭代參數(shù)傳進來,map函數(shù)則會把每一個參數(shù)都以相應(yīng)的處理函數(shù)進行迭代處理。map()函數(shù)接收兩個參數(shù),一個是函數(shù),一個是序列,map將傳入的函數(shù)依次作用到序列的每個元素,并把結(jié)果作為新的map返回。
l = [1,2,3]
new_list = list(map(lambda i: i+1, l))
print(new_list)
# Py3里,外面需要套個list:
# 這是為了讓里面的值給顯示出來,要不然你會得到這是個map函數(shù)
# 而不是里面的值。
# Py2的童鞋不虛
# 輸出[2, 3, 4]
# 我們也可以把兩個數(shù)組搞成一個單獨的數(shù)組
l2 = [4,5,6]
new_list = list(map(lambda x,y: x+y, l, l2))
print(new_list)
# 輸出[5, 7, 9]
- filter
filter()函數(shù)可以對序列做過濾處理,就是說可以使用一個自定的函數(shù)過濾一個序列,把序列的每一項傳到自定義的過濾函數(shù)里處理,并返回結(jié)果做過濾。最終一次性返回過濾后的結(jié)果。 和map()類似,filter()也接收一個函數(shù)和一個序列。和map()不同的時,filter()把傳入的函數(shù)依次作用于每個元素,然后根據(jù)返回值是True還是False決定保留還是丟棄該元素。
l = [100, 20, 24, 50, 110]
new = list(filter(lambda x: x<50, l))
# 同理,py3得套個list來轉(zhuǎn)化成list函數(shù),便于打印出來
print(new)
# 輸出 [20, 24]
【參考資料】:
- sys.path.append()的使用
-
os.path.join()的使用
(內(nèi)容來自網(wǎng)絡(luò),侵刪)