【问题标题】:Python version independent string handlingPython 版本无关的字符串处理
【发布时间】:2023-03-13 16:56:01
【问题描述】:

我对字符串与字节数组的区别很满意。 Python3 区分字符串和字节,python2 不太清楚。美好的。 考虑这两行代码:

a=b'AAA'  #a bytes array seen from Python3, a string/bytes for python2
b='BBB'   #a string for python3, a string/bytes for python2

我想写一些代码转换,在这里,连接ab并返回一个字节/字符串(在python2中)或字节数组(在python3中)。 (预期结果beeing - 视为ASCII char- AAABBB)

换句话说,我想要一个与 python 版本无关的行,相当于:

result = a+b #returns a string/bytes in python2

result = a+bytes(b,'utf-8') #returns a bytes array in python3

我希望这行代码可以在 python 2 和 3 上运行(无需更改)并避免花哨的非标准包(结构可以),因为它可以在嵌入式系统上运行。

如果您想知道哪种编码,我最好的选择是最接近 8 位扩展 ASCII 表的编码(256 个值:我可能有反斜杠或欧洲字符,但没有中文)

到目前为止,我发现的最好的是: 结果 = a + b.encode('ASCII')

这是 ASCII 字符 >127 的问题。我尝试使用 'cp437',但它似乎默认为 ascii...

@martineau 提出的尝试:

Python 3.6.7 (default, Oct 22 2018, 11:32:17)
[GCC 8.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> a=b'aaa'
>>> b='bbbä'
>>> a+b
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: can't concat str to bytes
>>> a+bytes(b,'latin1')
b'aaabbb\xe4'


Python 2.7.15rc1 (default, Nov 12 2018, 14:31:15) 
[GCC 7.3.0] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> a=b'aaa'
>>> b='bbbä'
>>> a+b
'aaabbb\xc3\xa4'
>>> a+bytes(b,'latin1')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: str() takes at most 1 argument (2 given)

【问题讨论】:

  • 为什么不直接说b = b'BBB'
  • 尝试使用b.encode('latin1')
  • @martineau: with python 2: >>> 'bbbä'.encode('latin1') Traceback(最近一次调用最后):文件“”,第 1 行,在 UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 3: ordinal not in range(128) 看来我的编码器只是被忽略了。
  • 请在您的问题中添加示例代码以重现问题。
  • 第二,不使用UTF8编码有什么原因吗?这是迄今为止处理文本和编码问题时最常见的标准,因此除非您有充分的理由,否则这就是要使用的编码。就这些问题编写代码以在 Py2 和 Py3 中正常工作并非易事,但这样做的方法是不要纠结使用哪种编码(例如 Latin1 与 Foobar);相反,它是学习 Unicode-Sandwich 模式并使用(或借用一些逻辑)六库。

标签: python python-3.x string


【解决方案1】:

我建议查看six,这是一个专门设计用于处理(部分)Python 2 和 Python 3 之间差异的 Python 模块。特别是,函数 ensure_binary(请参阅 https://six.readthedocs.io/#six.ensure_binary)可以解决您的问题。

请注意,我了解您希望避免依赖“花哨的第三方库”,但 six 不是“花哨的”;)但是,我不知道它在嵌入式系统上的开销是多少。

【讨论】:

    【解决方案2】:

    我不知道真正的版本“不可知”的做法,但以下似乎非常接近理想,适用于 Python 2.7.16 和 3.7.2:

    a = b'aaa'
    b = 'bbb\xc2\x84'
    
    try:
        b = bytes(b, 'latin1')
    except TypeError:
        b = bytes(b)
    
    c = a + b
    
    print(repr(c))  # -> 'aaabbb\xc2\x84'
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-03-22
      • 2018-01-17
      • 1970-01-01
      • 1970-01-01
      • 2015-10-21
      • 2016-09-01
      • 1970-01-01
      • 2020-03-12
      相关资源
      最近更新 更多