Регистрация - Вход

Реклама на сайте


От Perl-скрипта к Twisted-приложению: Переходим на Unicode


В случае, если предполагается, что приложение будет работать более чем с одной кодировкой, то оправдано использование 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. В следующий раз будем писать юнит-тесты.

Источники: pyobject.ru


КОММЕНТАРИИ







Теги


RSS

Архив



газоны уход. согласование перепланировки все узаконить перепланировку