- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
目前,我有 Python 2.7 代码接收 <str>
通过套接字连接的对象。在整个代码中,我们使用 <str>
对象、比较等。为了转换为 Python 3,我发现套接字连接现在返回 <bytes>
需要我们将所有文字更改为类似 b'abc'
的对象进行字面比较等。这需要大量工作,虽然很明显为什么要在 Python 3 中进行此更改,但我很好奇是否有任何更简单的解决方法。
假设我收到 <bytes> b'\xf2a27'
通过套接字连接。有没有简单的方法来转换这些 <bytes>
进入<str>
在 Python 3.6 中具有相同转义的对象?我自己研究了一些解决方案,但无济于事。
a = b'\xf2a27'.decode('utf-8', errors='backslashescape')
以上产量 '\\xf2a27'
与 len(a) = 7
而不是原来的 len(b'\xf2a27') = 3
.索引也是错误的,这是行不通的,但它似乎正朝着正确的方向前进。
a = b'\xf2a27'.decode('latin1')
以上产量 'òa27'
其中包含我想避免的 Unicode 字符。虽然在这种情况下 len(a) = 5
和类似 a[0] == '\xf2'
的比较工作,但如果可能的话,我希望在表示中对信息进行转义。
我是否缺少更优雅的解决方案?
最佳答案
您确实必须考虑收到的数据代表什么,而 Python 3 在这方面发挥了重要作用。实际上表示字节集合的字节串与(抽象,unicode)字符的字符串之间存在重要区别。
如果每条数据可以有不同的表示,您可能需要单独考虑它们。
让我们以 b'\xf2a27'
为例,您从套接字接收到的原始格式只是一个 4 字节的字符串:0xf2
, 0x61
、0x32
、0x37
(十六进制)或 242
、97
、50
, 55
十进制。
假设您实际上需要其中的 4 个字节。您可以将其保留为字节字符串,也可以将其转换为字节的 list
或 tuple
,如果这对您更好的话:
raw_bytes = b'\xf2a27'
list_of_bytes = list(raw_bytes)
tuple_of_bytes = tuple(raw_bytes)
if raw_bytes == b'\xf2a27':
pass
if list_of_bytes == [0xf2, 0x61, 0x32, 0x37]:
pass
if tuple_of_bytes == (0xf2, 0x61, 0x32, 0x37):
pass
假设这实际上表示一个 32 位整数,在这种情况下,您应该将其转换为 Python int
。选择它是以小字节序还是大字节序编码,并确保您选择了正确的有符号和无符号字节顺序。
raw_bytes = b'\xf2a27'
signed_little_endian, = struct.unpack('<i', raw_bytes)
signed_little_endian = int.from_bytes(raw_bytes, byteorder='little', signed=True)
unsigned_little_endian, = struct.unpack('<I', raw_bytes)
unsigned_little_endian = int.from_bytes(raw_bytes, byteorder='little', signed=False)
signed_big_endian, = struct.unpack('>i', raw_bytes)
signed_big_endian = int.from_bytes(raw_bytes, byteorder='big', signed=True)
unsigned_big_endian, = struct.unpack('>I', raw_bytes)
unsigned_big_endian = int.from_bytes(raw_bytes, byteorder='big', signed=False)
if signed_litte_endian == 926048754:
pass
假设它实际上是文本。考虑一下它采用的编码方式。在您的情况下,它不能是 UTF-8,因为 b'\xf2'
将是一个无法正确解码为 UTF-8 的字节字符串。如果它是 latin1 a.k.a. iso8859-1 并且您确定它,那很好。
raw_bytes = b'\xf2a27'
character_string = raw_bytes.decode('iso8859-1')
if character_string == '\xf2a27':
pass
如果您选择的编码是正确的,那么在字符串中包含 '\xf2'
或 'ò'
字符也是正确的。它仍然是一个单一的字符。 'ò'
、'\xf2'
、'\u00f2'
和 '\U000000f2'
只是 4 个不同在 (unicode) 字符串文字中表示相同单个 字符的方法。此外,len 将为 4,而不是 5。
print(ord(character_string[0])) # will be 242
print(hex(ord(character_string[0]))) # will be 0xf2
print(len(character_string)) # will be 4
如果你实际观察到长度为 5,你可能观察到了错误的点。也许在将字符串编码为 UTF-8 或通过打印到 UTF-8 终端将其隐式编码为 UTF-8 之后。
注意更改默认 I/O 编码时输出到 shell 的字节数的差异:
PYTHONIOENCODING=UTF-8 python3 -c 'print(b"\xf2a27".decode("latin1"), end="")' | wc -c
# will output 5
PYTHONIOENCODING=latin1 python3 -c 'print(b"\xf2a27".decode("latin1"), end="")' | wc -c
# will output 4
理想情况下,您应该在将原始字节转换为它们代表的正确数据类型后执行比较。这使您的代码更具可读性和更易于维护。
作为一般经验法则,您应该始终在收到原始字节后立即将其转换为它们的实际(抽象)数据类型。然后将其保留在该抽象数据类型中,以便尽可能长时间地进行处理。如有必要,将其转换回输出的一些原始数据。
关于python - <bytes> 转义 <str> Python 3,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56641563/
你信吗?我有一个这样的循环(请原谅任何错误,我不得不大量编辑大量信息和变量名称,相信我它有效)。 ...旧示例已删除,请参见下面的代码... 如果我将那些中间的 str = "Blah\(odat.c
我正在做一个本地测试来比较 C# 中 String 和 StringBuilder 的 Replace 操作性能,但是对于 String 我使用了以下代码: String str = "String
我想知道为什么str += "A"和 str = str + "A"有不同的表现。 在实践中, string str = "cool" for(int i = 0; i approximately
我有一个类型列表 [("['106.52.116.101']", 1), ("['45.136.108.85']", 1)] 并想将其转换为 [('106.52.116.101', 1), ('45.
我有一个类型列表 [("['106.52.116.101']", 1), ("['45.136.108.85']", 1)] 并想将其转换为 [('106.52.116.101', 1), ('45.
我正在遍历 HashMap并通过一些本地变量中的模式匹配将值放入其中。 委托(delegate)者 fn lyrics_no_bottles(song_template:&mut String){
如果字符串(短语)中只有元音,它(对我而言)说True;否则说 False。我不明白为什么它总是返回 False,因为 (x >= x) 总是返回 True。我感谢任何人检查此查询的解决方案。 (st
我有代码以某种方式转换字符串引用,例如取第一个字母 trait Tr { fn trim_indent(self) -> Self; } impl Tr for &'a str { f
我正在学习指针,这是我的代码。我定义了一个指向 char(实际上是字符串)的指针 *str 和一个指向 int *a 的指针,它们的定义方式相同。我认为 str 和 a 都应该是一个地址,但是当我试图
为什么我会收到错误消息?我已经正确添加了类型,对吗? Invalid index type "str" for "Union[str, Dict[str, str]]"; expected type
你知道下面两个函数是否等价吗? function validate(str) { return ( ['null','','undefined'].indexOf(str) [v, valida
我正在解决这里的 Dataquest 问题:https://app.dataquest.io/m/293/data-cleaning-basics/5/removing-non-digit-chara
我有一个字符串列表,如下所示: ["A TB", "A-R TB", "B TB", "B-R TB", "C TB", "C-R TB"...] 但字符串的顺序是随机的。我如何编写一个将元素配对的函
我正在尝试将此函数从使用 split 改为使用 str.extract (正则表达式)。 def bull_lev(x): spl = x.rsplit(None, 2)[-2].strip(
给定这样的数据结构: [{'a':1, 'b': 2}, {'c':3 }, {'a':4, 'c':9}, {'d':0}, {'d': 0, 'b':6}] 目标是解析数据以产生: {'a': 2
给定这样的数据结构: [{'a':1, 'b': 2}, {'c':3 }, {'a':4, 'c':9}, {'d':0}, {'d': 0, 'b':6}] 目标是解析数据以产生: {'a': 2
s = 'someString' s = QTreeWidgetItem(s) print(s.text(0)) # 0 being 'column' 输出: 's' 如果我对另一
黑白有什么区别: function(char* str ) function(char* str[] ) function(char str[] ) 它们是如何被调用的(通过什么类型的string/c
我试过谷歌搜索但找不到准确的答案,所以请允许我尝试在这里提问。如果问题看起来不合适,请告诉我,我会删除它。 在 JS 中,您可以通过三种不同的方式编写特定的内置功能: 字符串长度 str.toStri
我有这段代码(我的 strlen 函数) size_t slen(const char *str) { size_t len = 0; while (*str) {
我是一名优秀的程序员,十分优秀!