Originally published at
Pythy. You can comment here or
there.
В случае, если предполагается, что приложение будет работать более чем с одной
кодировкой, то оправдано использование unicode для внутреннего представления
данных. При таком решении, перекодировка осуществляется только на входе/выходе
данных и информация о кодировках "концентрируется" в этих местах, а не
"таскается" по всему приложению.
Если говорить про демо-приложение
TwistedPythy, то у транспорта и БД
кодировки вполне могут быть различными (например, у меня вышло, что у
транспорта cp866, а у БД - cp1251). Выделяю места, где будут происходить
перекодировки из/в unicode:
- вход транспорта (lineReceived), из строки в кодировке транспорта в unicode
- выход транспорта (sendLine), из unicode в строку в кодировке транспорта
- вход клиента (getClient), из unicode в строку в кодировке БД
- выход клиента (getClient), из строки в кодировке в кодировке БД в unicode
Во всех остальных местах и вход и выход - unicode.
Переписываем клиента DummyClient, чтобы он возвращал unicode, а не str,
называем его UnicodeDummyClient:
class UnicodeDummyClient(DummyClient):
"""Dummy client for testing purposes with I/O data in unicode"""
def getClient(self, agreem_num):
assert isinstance(agreem_num, unicode)
res = u'Dummy_%s' % agreem_num
if len(res) > 20:
res = res[:20]
# для имитации задержки выборки данных
time.sleep(self.pause_time)
return res
аналогичным образом изменяем и AsyncPythyProto:
class AsyncUnicodePythyProto(AsyncPythyProto):
"""
Simple text demo protocol with async method for fetching data
and internal data in unicode
"""
def lineReceived(self, line):
assert(line, str)
log.msg("data received from %s: `%s'" % (str(self.transport.client), line))
if line == '':
self.sendLine(u"Good bye")
self.transport.loseConnection()
return
# str -> unicode
line = line.decode(self.factory.encoding)
agr = line[10:15]
deferred = threads.deferToThread(self.factory.clients.getClient, agr)
deferred.addCallback(self._cbGetClient)
def sendAnswer(self, client):
assert isinstance(client, unicode)
packet = u'u0442u0435u0441u0442%s' % client
self.sendLine(packet)
def sendLine(self, line):
assert isinstance(line, unicode)
line = line.replace('r', '').replace('n', '')
# unicode -> str
line = line.encode(self.factory.encoding)
log.msg("data send: %s" % line)
line = line + "rn"
self.transport.write(line)
Вроде все. Код, по обычаю, - на
RapidShare.
P.S. В следующий раз будем писать юнит-тесты.