Latin-1和Python中的unicode工厂

eks*_*tso 6 python unicode

我有一个Python 2.6脚本,它使用拉丁文1编码的特殊字符,我从SQL Server数据库中检索.我想打印这些字符,但我有点受限,因为我使用的是一个调用unicode工厂的库,我不知道如何让Python使用除了以外的编解码器ascii.

该脚本是一个简单的工具,可以从数据库返回查找数据,而无需直接在SQL编辑器中执行SQL.我使用PrettyTable 0.5库来显示结果.

脚本的核心是这段代码.我从游标中获得的元组包含整数和字符串数据,并且没有Unicode数据.(我会使用adodbapi而不是pyodbc,这会让我获得Unicode,但adodbapi给了我其他问题.)

x = pyodbc.connect(cxnstring)
r = x.cursor()
r.execute(sql)

t = PrettyTable(columns)
for rec in r:
    t.add_row(rec)
r.close()
x.close()

t.set_field_align("ID", 'r')
t.set_field_align("Name", 'l')
print t
Run Code Online (Sandbox Code Playgroud)

但该Name列可以包含超出ASCII范围的字符.prettytable.pyc当它进入t.add_row调用时,我有时会在第222行收到类似这样的错误消息:

UnicodeDecodeError: 'ascii' codec can't decode byte 0xed in position 12: ordinal not in range(128)
Run Code Online (Sandbox Code Playgroud)

这是第222行prettytable.py.它使用unicode,这是我的问题的根源,而不仅仅是在这个脚本中,而是在我编写的其他Python脚本中.

for i in range(0,len(row)):
    if len(unicode(row[i])) > self.widths[i]:   # This is line 222
        self.widths[i] = len(unicode(row[i]))
Run Code Online (Sandbox Code Playgroud)

请告诉我这里我做错了什么.如何在unicode没有黑客攻击prettytable.py或我使用的任何其他库的情况下开展工作?有没有办法做到这一点?

编辑:错误不是出现在print语句中,而是出现在t.add_row调用中.

编辑:在BastienLéonard的帮助下,我提出了以下解决方案.它不是灵丹妙药,但它有效.

x = pyodbc.connect(cxnstring)
r = x.cursor()
r.execute(sql)

t = PrettyTable(columns)
for rec in r:
    urec = [s.decode('latin-1') if isinstance(s, str) else s for s in rec]
    t.add_row(urec)
r.close()
x.close()

t.set_field_align("ID", 'r')
t.set_field_align("Name", 'l')
print t.get_string().encode('latin-1')
Run Code Online (Sandbox Code Playgroud)

我最终不得不在路上进行解码并在出路时进行编码.所有这些让我充满希望,每个人都可以将他们的库尽快移植到Python 3.x!

Bas*_*ard 6

在模块的开头添加:

# coding: latin1
Run Code Online (Sandbox Code Playgroud)

或者自己将字符串解码为Unicode.

[编辑]

自从我使用Unicode以来已经有一段时间了,但希望此示例将展示如何将Latin1转换为Unicode:

>>> s = u'ééé'.encode('latin1') # a string you may get from the database
>>> s.decode('latin1')
u'\xe9\xe9\xe9'
Run Code Online (Sandbox Code Playgroud)

[编辑]

文档:
http://docs.python.org/howto/unicode.html
http://docs.python.org/library/codecs.html

  • 您可能不想设置编码:latin1。这将更改脚本源而不是其数据的编码。 (2认同)