我想在我的应用程序中使用 gettext。
所以,我尝试像这样将基础知识放入 __ init__.py 中:
import gettext
_ = gettext.gettext
gettext.bindtextdomain ( 'brainz', '../datas/translations/' )
gettext.textdomain ( 'brainz' )
然后我尝试在 Brainz.py 中进行简单调用:
#!/usr/bin/python
from brainz import *
##
# Main class of the game
class Brainz :
def __init__ ( self ) :
print _( "BrainZ" )
print _( "There will be blood..." )
print _( "By %s" ) % "MARTIN Damien"
但是我在执行时有以下错误:
Traceback (most recent call last):
File "main.py", line 8, in <module>
Brainz ()
File "/home/damien/Dropbox/Projets/BrainZ/brainz/Brainz.py", line 12, in __init__
print _( "BrainZ" )
NameError: global name '_' is not defined
因为我是 python 的新手,所以我不明白哪里出了问题。
你能给我一些好的建议吗?
谢谢,
达米安
最佳答案
斯多兰 explained为什么您的代码不起作用,并提供了一个很好的解决方案。但这有一个不便之处:您必须在每个要启用翻译的模块中导入 gettext。
Elf Sternberg provided一种非常方便的方法:手动使 gettext 在项目范围内可见。但它看起来有点神秘,正如他所说,它是纯粹的邪恶 :)。出于未知原因,他还建议使用完全不相关的 Django ugettext。不需要 Django,像以前一样坚持使用标准库 gettext。
我可以建议第三个,officially endorsed方法?在您之前尝试过的同一个 __init__.py
中,使用:
import gettext
gettext.install('brainz', '../datas/translations/')
就是这样! 项目范围内的 _()
可用性,以一种非神秘、优雅和方便的方式,使用标准gettext
模块。但是,公平地说,如果您查看 gettext 的源代码,您会发现它使用了 Elf 建议的相同技巧。所以,从本质上讲,这也是 Pure Evil(tm)。但是,如果“brainz”模块仅由您的应用程序使用,而不打算由其他应用程序导入,这就完全没问题了。
如果你想与其他应用程序共享'brainz',你应该使用sdolan的方法:在每个模块中导入它。但是,再次强调,不要像您那样使用 bindtextdomain
和 textdomain
,我建议这样做:
import gettext
t = gettext.translation('brainz', '../datas/translations/')
_ = t.ugettext
区别在于使用 gettext 的基于类的 API 而不是 GNU gettext API。看看 official reference为什么。 install
方法也是基于类的 API 的一部分。
旁注:您会注意到文档建议使用 pygettext
作为 GNU 的 xgettext
的替代品。 不要! Pygettext 极度过时并且缺少一些功能。 xgettext
更加强大和灵活,并且完全支持 Python。
关于 python : using gettext everywhere with __init__. py,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3834457/