我想通过我的应用程序使用gettext.
所以,我试着把基础知识放到__ init__.py中,如下所示:
import gettext
_ = gettext.gettext
gettext.bindtextdomain ( 'brainz', '../datas/translations/' )
gettext.textdomain ( 'brainz' )
Run Code Online (Sandbox Code Playgroud)
我在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"
Run Code Online (Sandbox Code Playgroud)
但是我在执行时遇到以下错误:
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
Run Code Online (Sandbox Code Playgroud)
因为我是python的新手,我不明白出了什么问题.
你能给我一些好建议吗?
谢谢,
达米安
通配符导入不会导入以下划线开头的任何内容.
通配符很糟糕,它们会污染命名空间,并且很难找到错误.此外,_有时用于表示未使用的变量.
只需在您需要的地方进行导入即可.它只有一行,因此输入并不难,您可以随时在IDE中创建一个片段.
更新:请参阅http://python.net/~goodger/projects/pycon/2007/idiomatic/handout.html#importing,以了解更多不使用通配符的原因.
sdolan 解释了为什么你的代码不起作用,并提供了一个很好的解决方案.但它带来了不便:您必须在要启用翻译的每个模块中导入gettext .
Elf Sternberg 提供了一种非常方便的方法:手动使gettext在项目范围内可见.但它看起来有点神秘,正如他所说,这是纯粹的邪恶:).由于一个未知的原因,他还建议完全不相关的Django ugettext.不需要Django,坚持像以前一样使用标准的lib gettext.
我可以建议第三种,正式认可的方法吗?在__init__.py你之前尝试过的,使用这个:
import gettext
gettext.install('brainz', '../datas/translations/')
Run Code Online (Sandbox Code Playgroud)
就是这样!_()使用标准gettext模块,以非神秘,优雅和方便的方式实现项目范围内的可用性.但是,公平地说,如果你看一下gettext的源代码,你会发现它使用了Elf建议的相同技巧.所以,从本质上讲,这也是Pure Evil(tm).但是,如果'brainz'模块仅由您的应用程序使用并且不打算由其他应用程序导入,那么这是完全正常的.
如果你想与其他应用程序共享'brainz',你应该使用sdolan的方法:在每个模块中导入它.但同样的,而是采用bindtextdomain和textdomain像你这样,我的建议是:
import gettext
t = gettext.translation('brainz', '../datas/translations/')
_ = t.ugettext
Run Code Online (Sandbox Code Playgroud)
区别在于使用gettext的基于类的API而不是GNU gettext API.看看为什么的官方参考.该install方法也是基于类的API的一部分.
旁注:您会注意到文档建议pygettext用作GNU的替代品xgettext.别!Pygettext 非常过时,缺乏一些功能.xgettext功能更强大,更灵活,完全支持Python.
| 归档时间: |
|
| 查看次数: |
3196 次 |
| 最近记录: |