糾結的Python2.7編碼與os.walk()函式的目錄引數
阿新 • • 發佈:2018-12-30
Python3與Python2.x系列的編碼處理(型別,檔案等)有所不同,具體這裡就不再介紹了,網上有很多相關文章。
這裡分享一個糾結了非常久的問題(因為一開始沒特別注意函式引數的編碼問題,所以浪費了不少時間,希望能給同樣遇到這個問題的朋友們一點幫助)。
os.walk()函式是在需要深度訪問一個目錄時經常要使用的,前段時間在寫一個toolkit(稍後陸續放出),裡面有個功能需要這個函式,以前使用時傳遞的引數都是英文的,所以沒太注意這個問題,沒想到這次在使用中文的時候麻煩就出現了。
def encrypt(dir,outfile,suffix,recursion): exts = suffix.split("|") all_files=[] print('傳入的目錄:'+dir.decode('gbk'))#請注意,print的時候需要decode下,不然是亂碼 #當前遞迴的目錄,當前遞迴的目錄下的所有子目錄,當前遞迴的目錄下的所有檔案 for root, dirs, files in os.walk(dir): print('正在呼叫...') for name in files: file_path=unicode(os.path.join(root,name),'gbk')#全稱,正確地取得windows下的中文檔名 extension=os.path.splitext(file_path)[1] if extension[:1]!='.': extension='.'+extension if extension in exts: oldfile=file_path extensionlen=-len(extension) newfile=oldfile[:extensionlen]+'-new'+extension os.rename(oldfile, newfile) all_files.append('/'.join(file_path.split('\\'))+"<>"+'/'.join(newfile.split('\\'))) if(not recursion): break if len(all_files)>0: file = open(outfile,"w") try: file.write("\n".join(all_files)) print('successfully writes %d lines(files).' %len(all_files)) finally: file.close() else: print('sorry,no files found!')
這兩個函式的功能是遍歷一個目錄下指定字尾名的檔案,並將其重新命名,之後將改變記錄到log檔案,待下次恢復時使用。
主要問題出現在dir變數,當裡面含有中文字元時,不會報錯,但是不會進入for root, dirs, files in os.walk(dir): 迴圈體,調了好久才發現這個問題,一開始就忽略了引數的編碼問題。後來意識到編碼後,糾結了好久才調正確,歸結起來有以下幾點需要注意:
windows中一般需要gbk編碼來與python的預設編碼(unicode,python3系列我還沒有嘗試)進行轉換;
在上面的函式中,所位於的python檔案編碼為utf-8(# -*- coding: UTF-8 -*-),所以引數dir變數需要先decode(’utf-8’),然後encode (’gbk’),decode可以省略;
當然在encrypt()函式中print時若需要看到正確的中文需要decode(’gbk’)。
最後一點教訓是,還是把編碼問題,尤其是python2.x的編碼搞清楚再去勇敢地使用中文吧,哎…
os.walk()可以使用字典儲存目錄結構資訊,例如:
import os
walker={}
for root,dirs,files in os.walk('/tmp'):
walker[root]=(dirs,files)
print walker.keys()
for p in walker:
print walker[p][1]