我可以将哪个函数应用于一个字符串变量,该变量会导致与b
修饰符前置字符串文字相同的结果?
我已在this question about the b
modifier for string literals in Python 2中读到将b
添加到字符串之前使其成为字节字符串(主要用于使用2to3
时Python 2和Python 3之间的兼容性)。我想获得的结果是相同的,但应用于变量,如:
def is_binary_string_equal(string_variable):
binary_string = b'this is binary'
return convert_to_binary(string_variable) == binary_string
>>> convert_to_binary('this is binary')
[1] True
convert_to_binary
的正确定义是什么?
答案 0 :(得分:4)
首先请注意,在Python 2.x中,b
前缀实际上什么也没做。 b'foo'
和'foo'
都是完全相同的字符串文字。仅存在b
以允许您编写与Python 2.x和Python 3.x兼容的代码:您可以使用b'foo'
来表示“我想要两个版本中的字节”,以及{{ 1}}表示“我希望在两个版本中使用Unicode”,并且只是简单地u'foo'
表示“我想在两个版本中都使用默认的'foo'
类型,即使这是3.x中的Unicode和字节中的2.X”。
所以,“在Python 2中将'b'字符前缀为字符串文字的功能相当于”根本就什么都不做。
但是我们假设您实际上有一个Unicode字符串(就像您从Python 3中的普通文字或文本文件中获得的那样,即使在Python 2中,您只能通过显式解码或使用某些函数来获取这些字符串为你做这件事,比如用str
打开一个文件。因为那是一个有趣的问题。
简短的回答是:codecs.open
。
但在你能做到之前,你需要知道你想要的编码。您不需要使用文字字符串,因为当您在源代码中使用string_variable.encode(encoding)
前缀时,Python 知道您想要的编码:与源代码文件相同的编码。 *但是你打开和阅读的源代码文件,输入用户类型,通过套接字传入的消息以外的所有内容都可以是任何,而Python不知道;你必须告诉它。 **
在许多情况下(特别是如果您使用的是最近的非Windows机器并处理本地数据),可以安全地假设答案是UTF-8,因此您可以将b
拼写为{ {1}}。但“很多”并非“全部”。***这就是文本编辑器和网络浏览器让用户选择编码的原因 - 因为有时只有用户真正知道。
*请参阅PEP 263了解如何指定编码以及您希望的原因..
**您也可以使用convert_to_binary_string(string_variable)
,这是string_variable.encode('utf8')
的同义词。并且,在这两种情况下,您可以不使用bytes(s, encoding)
参数 - 但是它默认为比您实际想要的更可能是ASCII的东西,所以不要这样做。
***例如,许多较旧的网络协议被定义为Latin-1。许多Windows文本文件是在OEM字符集设置为 - 通常是美国系统上的cp1252的情况下创建的,但还有数百种其他可能性。有时候s.encode(encoding)
或encoding
会获得您想要的内容,但是,当您正在处理某人上传的他的计算机首选编码时,这显然不起作用,不是你的。
在特殊情况下,相关的编码是“无论这个特定的源文件是什么”,你几乎必须知道某种程度的带外。*一旦脚本或模块被编译和加载,它就不是可以更长时间地分辨它最初的编码。**
但是没有太多理由要这样做。毕竟,如果两个二进制字符串相同,并且在相同的编码中,Unicode字符串也相等,反之亦然,因此您只需将代码编写为:
sys.getdefaultencoding()
* 默认当然是记录在案的 - 它是针对3.0的UTF-8,针对2.x的ASCII或Latin-1,具体取决于您的版本。但是你可以覆盖它,正如PEP 263解释的那样。
**好吧,您可以使用locale.getpreferredencoding()
模块查找源代码,然后使用def is_binary_string_equal(string_variable):
binary_string = u'this is binary'
return string_variable == binary_string
模块开始处理它等等 - 但这只有在文件仍然存在时才有效自上次编辑以来,尚未编辑过。
答案 1 :(得分:0)
请注意,在Linux机器上执行的python 3.7中,使用.encode('UTF-8')
和b'string'并不相同。
它给我的一个项目带来很多麻烦,直到今天,我仍然不清楚为什么会发生这种情况,但是我在Python 3.7中做到了
print('\xAD\x43\x48\x49\x44\x44\x49\x4E\x47\x53\x54\x4F\x4E\x45'.encode('UTF-8'))
print(b'\xAD\x43\x48\x49\x44\x44\x49\x4E\x47\x53\x54\x4F\x4E\x45')
在控制台上返回
b'\xc2\xadCHIDDINGSTONE'
b'\xadCHIDDINGSTONE'