Python中的字节字符串

时间:2013-09-26 01:03:05

标签: python sql

你是否知道如何摆脱Python列表中字符串前面的字节标识符,也许有一些可以修改的全局设置?

我从Postgres 9.3中检索一个查询,并创建一个查询的列表表单。看起来Python 3.3在类型为char(4)的列中解释记录,就像它们是字节字符串一样,例如:

Funds[1][1]
b'FND3'
Funds[1][1].__class__
<class 'bytes'>

所以暗示是:

Funds[1][1]=='FND3'
False

我可以控制该数据库,因此我可以将列类型更改为varchar(4),并且效果很好:

Funds[1][1]=='FND3'
True

但这只是一个临时解决方案。 小b使我的生活成为过去两天的噩梦;),我将非常感谢你对这个问题的帮助。

谢谢和问候 彼得

2 个答案:

答案 0 :(得分:2)

您必须手动实施__str__ / __repr__,或者,如果您愿意承担风险,请对字符串执行某种正则表达式替换。

示例__repr__

def stringify(lst):
    return "[{}]".format(", ".join(repr(x)[1:] if isinstance(x, bytes) else repr(x) for x in lst))

答案 1 :(得分:1)

b不是字符串的一部分,不仅仅是它周围的引号;当你打印出字符串时,它们只是表示的一部分。所以,你正在追逐错误的问题,一个不存在的问题。

问题是字节字符串b'FND3'与字符串'FND3'不同。在这个特定的例子中,这可能看起来很愚蠢,但如果你可能在任何地方都有任何非ASCII字符,它就会停止愚蠢。

例如,字符串'é'与Latin-1中的字节字符串b'\xe9'相同,它也与UTF-8中的字节字符串b'\xce\xa9'相同。当然b'\xce\a9'与Latin-1中的字符串'é'相同。

因此,您必须明确说明您正在使用的编码:

Funds[1][1].decode('utf-8')=='FND3'

但是为什么PostgreSQL会返回字节字符串?嗯,这就是char列。由Python绑定决定如何处理它们。并且不知道您使用的多个PostgreSQL绑定中的哪个,以及哪个版本,都无法告诉您该怎么做。但是,例如,在recent-ish psycopg中,您只需在连接中设置encoding(例如conn.set_client_encoding('UTF-8');在旧版本中,您必须注册标准类型规范并执行更多操作;等等;在py-postgresql中你必须注册lambda s: s.decode('utf-8');等等。