2016-11-26 47 views
1

我想通過Python寫入提交散列文件。所以我做:管道git提交散列到Python中的文件

f = open('git.txt', 'w') 
f.write(str(subprocess.check_output(['C:/Program Files/Git/bin/git', 'rev-parse', 'HEAD']))) 
f.close() 

但這寫了下面的提交:

b'714548ca074bd6e7c40973375e32413e63a67027\n' 

我想只是:

714548ca074bd6e7c40973375e32413e63a67027 

我可怎麼辦呢?

+1

不妨在這裏使用'with open(...)as'。請注意,在Python 2.7中,strings *是*字節字符串,所以問題僅在Python 3.x中顯示。(這與Git本身無關;任何使用'subprocess'運行的東西都會以這種方式運行,因爲子進程會產生字節流。) – torek

回答

2

這只是一個byte字符串。所有你需要做的是decode它寫它之前:

r = subprocess.check_output(['C:/Program Files/Git/bin/git', 'rev-parse', 'HEAD']) 
f.write(r.strip().decode()) 

r.strip()被稱爲去除拖尾'\n',則可以選擇做r[:-1].decode()如果你喜歡的。

此外,正如@torek所說,最好使用with語句打開文件,該語句會自動爲您關閉它。

所以:

# add .strip().decode() at the end if you want a single line statement. 
res = subprocess.check_output(['C:/Program Files/Git/bin/git', 'rev-parse', 'HEAD']) 
with open('git.txt', 'w') as f: 
    f.write(res.strip().decode()) 
+0

你可以在一行代碼中做到這一點嗎? – KcFnMi

+0

@KcFnMi肯定,但它會變得很長,我決定把它制動,讓它在眼睛上更容易一些。 :-) –

0

在Python 3,subprocess.check_output回報bytes對象,而不是str字符串:

默認情況下,該函數將返回數據作爲編碼的字節。輸出數據的實際編碼可能取決於被調用的命令,因此解碼到文本通常需要在應用程序級別進行處理。

不過,如果你有信心,你會得到你的平臺的默認編碼數據(足夠安全,在這裏),你可以設置參數universal_newlinesTrue

如果universal_newlinesTrue ,這些文件對象將使用locale.getpreferredencoding(False)返回的編碼以universal newlines模式作爲文本流打開。

這也將處理常見的空白煩惱,如行尾字符(顧名思義)。

下面是返回Git的輸出作爲一個字符串的函數,使用universal_newlines

def git_hash(commit_name='HEAD'): 
    git_command = 'C:/Program Files/Git/bin/git' 
    hash_string = subprocess.check_output(
     [git_command, 'rev-parse', commit_name], 
     universal_newlines=True 
    ) 
    return hash_string 

這裏是字符串寫入文件的例子:

fname = 'C:/temp/git_hash.txt' 
with open(fname, 'w') as f: 
    f.write(git_hash()) 

它使用with open(...):語法這是在評論中建議的,也是在The Python Tutorial。它(不幸)隱藏得很好,出現在7.2.1. Methods of File Objects的末尾。