Вопрос по ctypes, locale, glibc, python – Сортировка списка строк с определенной локалью в python

8

Я работаю над приложением, которое использует тексты на разных языках, поэтому для просмотра или составления отчетов некоторые тексты (строки) необходимо отсортировать на определенном языке.

В настоящее время у меня есть обходной путь с глобальными настройками локали, что плохо, и я не хочу запускать его в производство:

default_locale = locale.getlocale(locale.LC_COLLATE)

def sort_strings(strings, locale_=None):
    if locale_ is None:
        return sorted(strings)

    locale.setlocale(locale.LC_COLLATE, locale_)
    sorted_strings = sorted(strings, cmp=locale.strcoll)
    locale.setlocale(locale.LC_COLLATE, default_locale)

    return sorted_strings

Официальная документация по языку Python прямо говорит, что сохранение и восстановление - плохая идея, но не дает никаких предложений:http://docs.python.org/library/locale.html#background-details-hints-tips-and-caveats

Ваш Ответ

3   ответа
3

Error: User Rate Limit ExceededError: User Rate Limit ExceededError: User Rate Limit ExceededError: User Rate Limit Exceeded

import icu # PyICU

def sorted_strings(strings, locale=None):
    if locale is None:
       return sorted(strings)
    collator = icu.Collator.createInstance(icu.Locale(locale))
    return sorted(strings, key=collator.getSortKey)

Error: User Rate Limit Exceeded

>>> L = [u'sandwiches', u'angel delight', u'custard', u'éclairs', u'glühwein']
>>> sorted_strings(L)
['angel delight', 'custard', 'glühwein', 'sandwiches', 'éclairs']
>>> sorted_strings(L, 'en_US')
['angel delight', 'custard', 'éclairs', 'glühwein', 'sandwiches']

Disadvantage:Error: User Rate Limit ExceededError: User Rate Limit ExceededError: User Rate Limit Exceededlocale.strcoll.


Error: User Rate Limit Exceededlocale.strxfrmError: User Rate Limit ExceededhackError: User Rate Limit Exceededrun your function in a different child process:

pool = multiprocessing.Pool()
# ...
pool.apply(locale_aware_sort, [strings, loc])

Disadvantage:Error: User Rate Limit Exceeded


Error: User Rate Limit Exceededthreading.LockError: User Rate Limit ExceededlocaleError: User Rate Limit ExceededreError: User Rate Limit Exceeded


Error: User Rate Limit ExceededCythonError: User Rate Limit Exceeded

Disadvantage:Error: User Rate Limit Exceeded

3

Error: User Rate Limit Exceeded

# -*- coding: utf-8
import ctypes


class Locale(object):
    def __init__(self, locale):
        LC_ALL_MASK = 8127
        # LC_COLLATE_MASK = 8
        self.libc = ctypes.CDLL("libc.so.6")
        self.ctx = self.libc.newlocale(LC_ALL_MASK, locale, 0)



    def strxfrm(self, src, iteration=1):
        size = 3 * iteration * len(src)
        dest =  ctypes.create_string_buffer('\000' * size)
        n = self.libc.strxfrm_l(dest, src, size,  self.ctx)
        if n < size:
            return dest.value
        elif iteration<=4:
            return self.strxfrm(src, iteration+1)
        else:
            raise Exception('max number of iterations trying to increase dest reached')


    def __del__(self):
        self.libc.freelocale(self.ctx)

Error: User Rate Limit Exceeded

locale1 = Locale('C')
locale2 = Locale('mk_MK.UTF-8')

a_list = ['а', 'б', 'в', 'ј', 'ќ', 'џ', 'ш']
import random
random.shuffle(a_list)

assert sorted(a_list, key=locale1.strxfrm) == ['а', 'б', 'в', 'ш', 'ј', 'ќ', 'џ']
assert sorted(a_list, key=locale2.strxfrm) == ['а', 'б', 'в', 'ј', 'ќ', 'џ', 'ш']

Error: User Rate Limit Exceeded

3

Error: User Rate Limit ExceededctypesError: User Rate Limit Exceeded

Error: User Rate Limit Exceeded

from contextlib import contextmanager
import locale

@contextmanager
def changedlocale(newone):
    old_locale = locale.getlocale(locale.LC_COLLATE)
    try:
        locale.setlocale(locale.LC_COLLATE, newone)
        yield locale.strcoll
    finally:
        locale.setlocale(locale.LC_COLLATE, old_locale)

def sort_strings(strings, locale_=None):
    if locale_ is None:
        return sorted(strings)

    with changedlocale(locale_) as strcoll:
        return sorted(strings, cmp=strcoll)

    return sorted_strings

Error: User Rate Limit Exceeded

Похожие вопросы