ライブラリ内のPython gettextモジュールとそれを使用するモジュールを同時に呼び出して設定できますか?
-
05-07-2019 - |
質問
翻訳が必要なテキストフィードバックを含むライブラリのコーディングです。
アプリのどこにでもインポートする_config.pyモジュールに次の行を追加します:
import gettext, os, sys
pathname = os.path.dirname(sys.argv[0])
localdir = os.path.abspath(pathname) + "/locale"
gettext.install("messages", localdir)
./ locale / lang_LANG / LC_MESSAGESに* .moファイルがあり、翻訳する必要があるすべての文字列に_()関数を適用します。
これで、ユーザー(おそらくプログラマー)が自分のメッセージを作成できる機能を追加しました。私は彼が基礎となる実装を気にしたくないので、彼をリンゴにして、それを次のような簡単なものにしたいです:
lib_object.message = "My message"
プロパティを使用してクリーンにしましたが、ユーザーが自分のコード(私のコードを使用)を翻訳して、次のようなことをした場合はどうなりますか。
import gettext, os, sys
pathname = os.path.dirname(sys.argv[0])
localdir = os.path.abspath(pathname) + "/locale"
gettext.install("user_app", localdir)
lib_object.message = _("My message")
それは問題ですか?ユーザーを煩わせることなくトラブルを回避するにはどうすればよいですか?
解決
クラスベースのgettext apiを使用して、メッセージカタログを分離できます。これは、 python gettextドキュメントでも推奨されています。
欠点は、あなたまたは他の開発者がgettextメソッドを使用するか、特定のgettextクラスにバインドされたローカルスコープで _()
メソッドを定義する必要があることです。独自の文字列カタログを持つクラスの例:
import gettext
class MyClass(object):
def __init__(self, locale_for_instance):
self.lang = gettext.translation("appname", localedir, \
locale=locale_for_instance)
def some_method(self, arg):
return self.lang.gettext("You called some method")
def other_method(self, arg): # does the same thing
_ = self.lang.gettext
return _("You called some method")
デコレータに _()
を追加するためのコードを貼り付けることができるので、それを必要とするすべてのメソッドには @with_local_gettext
(注、上記のテストは行っていませんが、うまく動作するはずです(tm)
目標がユーザーを煩わせないことである場合(そして彼はあまり良くない場合)、コードでクラスベースのアプローチを使用し、ユーザーにグローバルなアプローチを使用させることができると思います。
他のヒント
gettext.install()は1回しか使用できません。一般に、ライブラリの作業には役に立たない-gettext.install()は、それを呼び出すモジュールがプログラム全体を担当する場合にのみ正しいことを行います。ライブラリコードは、Mailmanが行うことと同様の処理を行う必要があります。このモジュールに適切な引数を渡すgettext()の独自のラッパーを使用し、それを使用したい各モジュールに '_'としてインポートします。