2017-08-07 63 views
1

我是Python3中的新手。 我有一個寫入文件的字符串的問題。python3將字符串寫入整個文件的方式

下面的字符串是我試圖寫入文件。

ÀH \x10\x08\x81\x00(十六進制,c04820108810)

當我使用xxd命令,我可以檢查有字符串和文件之間的差異檢查的文件。

00000000: c380 4820 1008 c281 00     ..H ..... 

這是我寫的代碼。

s = 'ÀH \x10\x08\x81\x00' 
with open('test', 'w') as f: 
    f.write(s) 

問題是如何將這個字符串寫入文件的整體。

+1

你想把它寫成二進制嗎?然後使用'bytes',而不是'str':'s =b'ÀH\ x10 \ x08 \ x81 \ x00''。 – poke

回答

1

看來你想編寫二進制數據。在這種情況下,您應該使用bytes類型而不是str,因爲這樣可以完全控制序列的二進制內容。

在處理字符串時,您必須考慮到Python將內部處理爲UTF-8的所有內容,因此在輸入類似À之類的內容時,文件編碼將決定實際輸入的內容。您可以隨時encode()字符串來看看它的字節:

>>> 'ÀH \x10\x08\x81\x00'.encode() 
b'\xc3\x80H \x10\x08\xc2\x81\x00' 

您可以將這種使用binascii模塊對於那些字節更可讀的十六進制字符串爲十六進制:

>>> binascii.hexlify('ÀH \x10\x08\x81\x00'.encode()) 
b'c38048201008c28100' 

正如你所看到的,這與寫入文件的內容相同。所以Python已經做了正確的事情。這只是輸入不是你想要的。

所以取而代之,用一個字節字符串寫入到二進制模式的文件:

# use a bytes string 
s = b'\xc0\x48\x20\x10\x88\x10' 

# open the file in binary mode 
with open('test', 'bw') as f: 
    f.write(s) 

順便說一句。如果您從頭開始查看編碼的字符串,那麼在輸入該字符串時,您已經可以看到您在編碼方面比使用Python不同。你期望À是二進制的0xc0,這是因爲它的Latin-1表示有點正確。但是,如果您使用lookup its other representations,則可以看到在默認情況下Python使用的UTF-8中,它是0xc380,而這又是我們在Python中對其進行編碼時的值。

+0

字符串不是靜態的。在這種情況下,字符串被偶然顯示爲Latin-1表示。如果它是動態的,我怎樣才能將字符串轉換爲像b'\ xc0 \ x48 \ x20 \ x10 \ x88 \ x10'這樣的字節? – junsang

+0

我在答案中給出了你,你可以在字符串上調用'.encode()'將其轉換爲字節字符串。如果你不想使用UTF-8,你也可以指定一個不同的編碼,例如('latin-1')'。' - 'x'x'x8'x81'x00'。但這一切都取決於你的輸入來自哪裏。如果你真的在這裏處理二進制文件,它不應該在解碼字符串中。 – poke

+0

我明白了。非常感謝。你的回答和評論對我很有幫助。 – junsang

-1

您必須將編碼樣式設置爲utf-8,並使用原始字符串,因爲您有\轉義字符。因此,添加編碼風格並在你的字符串之前放入r以使其變爲原始。

# -*- coding: utf-8 -*- 
s = r'ÀH \x10\x08\x81\x00' 
with open('test.txt', 'w') as f: 
    f.write(s) 
+0

儘管如此,我得到了相同的結果... – junsang

+1

默認情況下,Python 3已經是UTF-8,不需要指定文件編碼。 – poke

+0

@poke謝謝了 –