Я просто нашел этот ответ в сети:
import unicodedata
def remove_accents(input_str):
nfkd_form = unicodedata.normalize('NFKD', input_str)
only_ascii = nfkd_form.encode('ASCII', 'ignore')
return only_ascii
Это хорошо работает (для французского языка, например), но я думаю, что второй шаг (удаляющий диакритические знаки) мог быть обработан лучше, чем отбрасывание символов неASCII, потому что это перестанет работать для некоторых языков (греческий язык, например). Лучшее решение состояло бы в том, чтобы, вероятно, явно удалить unicode символы, которые отмечены как являющийся диакритическими знаками.
Редактирование : это добивается цели:
import unicodedata
def remove_accents(input_str):
nfkd_form = unicodedata.normalize('NFKD', input_str)
return u"".join([c for c in nfkd_form if not unicodedata.combining(c)])
unicodedata.combining(c)
возвратит true, если символ c
может быть объединен с предшествующим символом, который является главным образом, если это - диакритический знак.
Редактирование 2 : remove_accents
ожидает строка unicode, не строка байтов. Если у Вас есть строка байтов, то необходимо декодировать ее в строку unicode как это:
encoding = "utf-8" # or iso-8859-15, or cp1252, or whatever encoding you use
byte_string = b"café" # or simply "café" before python 3.
unicode_string = byte_string.decode(encoding)
Вы можете обернуть сам вызов в объект, который обрабатывает отображение сообщения о загрузке, возможно, повторяя несколько раз при ошибках или что-то еще. Примерно так:
public abstract class AsyncCall<T> implements AsyncCallback<T> {
/** Call the service method using cb as the callback. */
protected abstract void callService(AsyncCallback<T> cb);
public void go(int retryCount) {
showLoadingMessage();
execute(retryCount);
}
private void execute(final int retriesLeft) {
callService(new AsyncCallback<T>() {
public void onFailure(Throwable t) {
GWT.log(t.toString(), t);
if (retriesLeft <= 0) {
hideLoadingMessage();
AsyncCall.this.onFailure(t);
} else {
execute(retriesLeft - 1);
}
}
public void onSuccess(T result) {
hideLoadingMessage();
AsyncCall.this.onSuccess(result);
}
});
}
public void onFailure(Throwable t) {
// standard error handling
}
...
}
Чтобы сделать вызов примерно таким:
new AsyncCall<DTO>() {
protected void callService(AsyncCallback<DTO> cb) {
DemoService.App.get().someService("bla", cb);
}
public void onSuccess(DTO result) {
// do something with result
}
}.go(3); // 3 retries
Вы можете расширить это с помощью кода, чтобы обнаруживать вызовы, которые занимают много времени, и отображать какой-то индикатор занятости и т. Д.
Вы можете создать суперкласс обратного вызова по умолчанию, который принимает аргумент объекта LoadingMessage
в своем конструкторе и предоставляет методы перехвата для подклассов, например onSuccess0
и onFailure0
.
Реализация будет похожа на:
public final void onFailure(Throwable caught) {
loadingMessage.hide();
onFailure0(caught);
}
protected abstract void onFailure0(Throwable caught);
Полный пример (Роберт)
public abstract class AsyncCall<T> implements AsyncCallback<T>
{
public AsyncCall()
{
loadingMessage.show();
}
public final void onFailure(Throwable caught)
{
loadingMessage.hide();
onCustomFailure(caught);
}
public final void onSuccess(T result)
{
hideLoadingMessage();
onCustomSuccess(result);
}
/** the failure method needed to be overwritte */
protected abstract void onCustomFailure(Throwable caught);
/** overwritte to do something with result */
protected abstract void onCustomSuccess(T result);
}