如何将Python的字节字符串表示转换为字节?

3
我有许多Python字节对象存储在文本文件中,Python以"b'\x80\x03}q\x00.'" 的形式打印。如何将它们转换回字节对象? 换句话说,我试图找到一个函数,使得 convert("b'\x80\x03}q\x00.'") == b'\x80\x03}q\x00.' 。我觉得这应该很简单,但以下这些明显的方法均未奏效:
>>> s = "b'\x80\x03}q\x00.'"
>>> bytes(s)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: string argument without an encoding
>>> bytes(s.encode())
b"b'\xc2\x80\x03}q\x00.'"
>>> bytes(s[2:-1].encode())
b'\xc2\x80\x03}q\x00.'
>>> bytes(s[2:-1].encode('utf8'))
b'\xc2\x80\x03}q\x00.'
>>> eval(s)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: source code string cannot contain null bytes
>>> exec(s)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: source code string cannot contain null bytes

1
你有bytes字面值的字符串表示,而不是bytes对象。这个文件最初是如何创建的? - chepner
1
实际上,你并没有一个bytes字面量。对于s =“...”,例如\x00会被替换为实际的空字节,而不是保留表示空字节的4个字符的字面值。如果你写s = r"...",那么 ast.literal_eval(s)将返回你想要的bytes对象。 - chepner
这取决于你在这个例子中如何设置s;如果s是从文件中读取的,例如s = f.readline(),那么这就不是一个问题。 - chepner
如果s是一个字符串,那么这个应该可以工作:str.encode(s)。s = "b'\x80\x03}q\x00.'" - Chetan_Vasudevan
1
bytes(s[2:-1].encode())[1:] # b'\x80\x03}q\x00.' - Darkonaut
我认为你一开始不应该将 byte-string 转换为 string!最好的方法是进行解码。例如:bs = b'\x80\x03}q\x00.',然后你应该写成 s = bs.decode(),这样你就可以随时使用 s.encode() 将其转换回 byte-string :) - Hamidreza
1个回答

5

这并不适用于从文件中读取 s 值的情况,但在你的示例中,普通字符串会扩展转义序列:

>>> s = "b'\x80\x03}q\x00.'"
>>> list(s)
['b', "'", '\x80', '\x03', '}', 'q', '\x00', '.', "'"]

请注意,s 中不包含空字节的转义序列;它包含一个实际的空字节。

您可以使用原始字符串字面值来避免这种情况:

>>> s = r"b'\x80\x03}q\x00.'"
>>> list(s)
['b', "'", '\\', 'x', '8', '0', '\\', 'x', '0', '3', '}', 'q', '\\', 'x', '0', '0', '.', "'"]

如果是这种情况,ast.literal_eval是您正在寻找的函数:

>>> ast.literal_eval(s)
b'\x80\x03}q\x00.'

原始字符串字面值应该生成您从文件中读取的值:
import ast

b = b'\x80\x03}q\x00.'

with open("tmp.txt", "w") as f:
    print(str(b), file=f)

with open("tmp.txt") as f:
    s = f.readline().strip()

assert ast.literal_eval(s) == b

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接