![](/img/trans.png)
[英]Python 3: How do I get a string literal representation of a byte string?
[英]Python 3, pythonic way to get the string literal representation of bytes?
有一個類似的問題 ,但是解決方案似乎不起作用。
假設我已經編碼了一個字符串:
>>> a = 'dada大大'.encode('utf-8')
>>> type(a)
<class 'bytes'>
>>> a
>>> b'dada\xe5\xa4\xa7\xe5\xa4\xa7'
我想要的是這樣的:
dada\xe5\xa4\xa7\xe5\xa4\xa7
str(a)
不起作用:
>>> str(a)
>>> "b'dada\\xe5\\xa4\\xa7\\xe5\\xa4\\xa7'"
我已經嘗試將stdout重定向到變量,但是仍然得到"b'dada\\\\xe5\\\\xa4\\\\xa7\\\\xe5\\\\xa4\\\\xa7'"
。
我可以使用正則表達式處理它並得到我想要的東西,但是我正在尋找一種更pythonic的方式來做到這一點。 有什么建議么?
由於您很樂意在評論中提及您的實際問題 ,因此我將再次更新我的答案以實際回答。 原始答案可以在下面看到。
這是我發布到Github Markdown API的字符串。 這是可以接受unicode字符的唯一方法。 我得到了帶有原始字符
dada大大
的渲染html
GitHub Markdown API要求您將數據作為JSON發送。 JSON本身借用了從JavaScript轉義的字符串,該字符為\大
。 但是,當使用json
模塊時,您完全不需要擔心:
from urllib import urlopen
import json
text = 'dada大大'
data = json.dumps({ mode: 'markdown', 'text': text }).encode()
r = urlopen('https://api.github.com/markdown', data)
print(r.read().decode()) # <p>dada大大</p>
如您所見,API可以毫無問題地接受編碼后的文本,並且可以正確生成正確的輸出,而不必擔心編碼。
或在requests
庫中使用原始API時:
h = { 'Content-Type': 'text/plain' }
r = requests.post('https://api.github.com/markdown/raw', text.encode(), headers=h)
print(r.content.decode()) # <p>dada大大</p>
>>> a = 'dada大大'.encode('utf-8')
>>> a
b'dada\xe5\xa4\xa7\xe5\xa4\xa7'
>>> str(a)
"b'dada\\xe5\\xa4\\xa7\\xe5\\xa4\\xa7'"
>>> str(a)[2:-1]
'dada\\xe5\\xa4\\xa7\\xe5\\xa4\\xa7'
>>> print(_)
dada\xe5\xa4\xa7\xe5\xa4\xa7
當您只執行str(a)
您將獲得字節字符串的字符串表示形式。 當然,當您在解釋器中像這樣使用它時,解釋器實際上會調用repr
來顯示它。 包含反斜杠的字符串會將其轉義為\\\\
。 那是那些來源。
最后,您必須去除b'
和結尾的'
以獲取字節字符串的字符串表示形式的內容。
旁注: str()
和repr()
在字節對象上使用時將產生相同的結果。
根據Poke的回答,我需要防止
repr
轉義。
不,你沒有。 最終字符串中沒有雙反斜杠。 它們之所以出現,是因為當您在REPL中輸入內容時,它將在調用repr
后將其返回值輸出到控制台。 但這並不意味着實際的字符串突然改變了:
>>> s = str(a)[2:-1]
>>> len(s)
28
>>> list(s)
['d', 'a', 'd', 'a', '\\', 'x', 'e', '5', '\\', 'x', 'a', '4', '\\', 'x', 'a', '7', '\\', 'x', 'e', '5', '\\', 'x', 'a', '4', '\\', 'x', 'a', '7']
如您所見,字符串中沒有雙反斜杠。 是的,您可以再次看到它們,但這僅是因為REPL正在打印list(s)
的返回值。 列表中的每個項目都是單個字符 ,包括反斜杠。 它們只是再次轉義,因為'\\'
不是有效的字符串。
>>> '\'
SyntaxError: EOL while scanning string literal
>>> '\\'
'\\'
>>> len('\\')
1
bytes
實際上是一個整數數組:
>>> a = 'dada大大'.encode() # 'utf-8' by default
>>> list(a)
[100, 97, 100, 97, 229, 164, 167, 229, 164, 167]
您可以使用以下方法獲取每個值的十六進制值
>>> list(map(hex, a))
['0x64', '0x61', '0x64', '0x61', '0xe5', '0xa4', '0xa7', '0xe5', '0xa4', '0xa7']
因此
>>> list(chr(x) if x < 128 else hex(x) for x in a)
['d', 'a', 'd', 'a', '0xe5', '0xa4', '0xa7', '0xe5', '0xa4', '0xa7']
>>> print("".join(chr(x) if x < 128 else hex(x).replace("0", "\\") for x in a))
dada\xe5\xa4\xa7\xe5\xa4\xa7
好的,最后我找到了解決方案,它來自Python用\\替換\\\\
a = 'dada大大'.encode('utf-8')
b = str(a)[2:-1].encode('utf-8').decode('unicode_escape')
也許我應該已經解釋了我想要更清楚的內容。
>>> import requests
>>> text = 'dada大大'
>>> h = {'Content-Type': 'text/plain'}
>>> r = requests.post('https://api.github.com/markdown/raw', text.encode(), headers=h)
>>> print(r.content.decode())
{"message":"Invalid request media type (expecting 'text/plain')","documentation_url":"http://developer.github.com/v3/markdown/#render-a-markdown-document-in-raw-mode"}
>>> print(r.content.decode('utf-8'))
{"message":"Invalid request media type (expecting 'text/plain')","documentation_url":"http://developer.github.com/v3/markdown/#render-a-markdown-document-in-raw-mode"}
>>> r = requests.post('https://api.github.com/markdown/raw', text.encode('utf-8'), headers=h)
>>> print(r.content.decode('utf-8'))
{"message":"Invalid request media type (expecting 'text/plain')","documentation_url":"http://developer.github.com/v3/markdown/#render-a-markdown-document-in-raw-mode"}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.