文件訪問與函數(shù)式編程(轉(zhuǎn)載)

一、文本文件讀寫

  1. 直接讀入
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()可以在讀行過程中跳過特定行。
  1. 文件迭代器,用for循環(huán)的方法
file2 = open("output.txt","w") 
for line in open("test.txt"): 
      #這里可以進行邏輯處理 
    file2.write('"'+line[:s]+'"'+",")
  1. 文件上下文管理器
#打開文件
#用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')

三、文件目錄的操作

  1. 基本操作
    用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(’引用模塊的地址') 
  1. 環(huán)境變量
    在操作系統(tǒng)中定義的環(huán)境變量,全部保存在os.environ這個dict中,可以直接查看.
os.environ
  1. 操作文件與目錄
    查看、創(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
  1. 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]
  1. 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]

【參考資料】:

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容