python:在 __init__.py 中随处使用 gettext
我想通过我的应用程序使用 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 新手,我不明白什么是错误的。
你能给我好的建议吗?
谢谢,
达米安
I would like to use gettext through my application.
So, I tried to put the basics into __ init__.py like this :
import gettext
_ = gettext.gettext
gettext.bindtextdomain ( 'brainz', '../datas/translations/' )
gettext.textdomain ( 'brainz' )
And I try simple call in 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"
But I have the following error at execution time :
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
As I'm new to python I don't understand what is wrong.
Could you give me good advices ?
Thanks,
Damien
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
sdolan 解释了为什么你的代码不起作用,并提供了一个很好的解决方案。但它有一个不便之处:您必须在每个要启用翻译的模块中导入 gettext。
Elf Sternberg提供了一种非常方便的方法:手动使 gettext 在项目范围内可见。但它看起来有点神秘,正如他所说,这是纯粹的邪恶:)。出于未知的原因,他还建议使用完全不相关的 Django ugettext。不需要 Django,像以前一样坚持使用标准 lib gettext。
我可以建议第三个,官方认可方法?在您之前尝试过的同一个
__init__.py
中,使用以下内容:就是这样! 项目范围
_()
使用标准gettext
模块,以一种公开、优雅且方便的方式实现可用性。但是,公平地说,如果您查看 gettext 的源代码,您会发现它使用了 Elf 建议的相同技巧。所以,本质上,这也是纯粹的邪恶(tm)。但是,如果“brainz”模块仅由您的应用程序使用并且不打算由其他应用程序导入,那么这完全没问题。如果你想与其他应用程序共享'brainz',你应该使用sdolan的方法:在每个模块中导入它。但是,我再次建议,不要像您那样使用
bindtextdomain
和textdomain
:区别在于使用 gettext 的基于类的 API,而不是 GNU gettext API。查看官方参考了解原因。
install
方法也是基于类的 API 的一部分。旁注:您会注意到文档建议使用
pygettext
作为 GNU 的xgettext
的替代品。 不要! Pygettext 极其过时,并且缺乏一些功能。xgettext
更加强大和灵活,并且完全支持Python。sdolan explained why your code didn't work, and provided a great solution. But it has an inconvenience: you have to import gettext in every module you want to enable translations.
Elf Sternberg provided a very convenient approach: manually make gettext visible project-wide. But it looks a bit cryptic and, as he said, it is pure evil :). He also suggests, for an unknown reason, the totally unrelated Django ugettext. No need of Django, stick with the standard lib gettext like you did before.
May I suggest a 3rd, officially endorsed approach? In the same
__init__.py
you tried before, use this:And that's it! Project-wide
_()
availability, in a non-cryptic, elegant and convenient way, using the standardgettext
module. But, to be fair, if you look at gettext's source code, you'll see that uses the same trick Elf suggested. So, in essence, this is also Pure Evil(tm). But this is perfectly fine if 'brainz' module is only used by your application and not meant to imported by other applications.If you want to share 'brainz' with other applications, you should use sdolan's approach: import it in each module. But, again, instead of using
bindtextdomain
andtextdomain
like you did, I suggest this:The difference is using gettext's Class-based API instead of the GNU gettext API. Take a look in the official reference for why. The
install
approach is also part of the Class-based API.Side note: you will notice the docs suggest using
pygettext
as a replacement for GNU'sxgettext
. Don't! Pygettext is extremely outdated and lacks several features.xgettext
is much more powerful and flexible, and fully supports Python.通配符导入不会导入以下划线开头的任何内容。
通配符很糟糕,它们会污染命名空间,并产生难以发现的错误。此外,
_
有时用于表示未使用的变量。只需在需要的地方进行导入即可。它只有一行,因此输入并不困难,而且您始终可以在 IDE 中创建一个代码片段。
更新:请参阅http:// python.net/~goodger/projects/pycon/2007/idiomatic/handout.html#importing 有更多理由不使用通配符。
Wildcard imports don't import anything beginning with an underscore.
Wildcards are bad, they pollute the namespace, and create hard to find bugs. Also, the
_
is sometimes used to denote an unused variable.Just do the import where you need it. It's only one line, so it's not hard to type in, and you could always create a snippet in your IDE.
UPDATE: See http://python.net/~goodger/projects/pycon/2007/idiomatic/handout.html#importing for even more reasons not to use wildcards.
这是纯粹的邪恶,但它却能如你所愿。在项目的 _init.py_ 根目录中,执行以下操作:
现在下划线将到处都是 ugettext。其他答案有适当的警告;修改 python VM 的内置列表并不是很好,而且它肯定会让任何不熟悉它的人感到困惑。
This is pure evil, but it does what you want. In the _init.py_ root of your project, do this:
And now the underscore will be ugettext everywhere. The other answers have appropriate caveats; modifying the python VM's builtins list isn't very nice, and it surely will confuse the hell out of anyone who's not familiar with it.