python:在 __init__.py 中随处使用 gettext

发布于 2024-09-26 06:33:21 字数 885 浏览 2 评论 0原文

我想通过我的应用程序使用 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

筑梦 2024-10-03 06:33:21

sdolan 解释了为什么你的代码不起作用,并提供了一个很好的解决方案。但它有一个不便之处:您必须在每个要启用翻译的模块中导入 gettext。

Elf Sternberg提供了一种非常方便的方法:手动使 gettext 在项目范围内可见。但它看起来有点神秘,正如他所说,这是纯粹的邪恶:)。出于未知的原因,他还建议使用完全不相关的 Django ugettext。不需要 Django,像以前一样坚持使用标准 lib gettext。

我可以建议第三个,官方认可方法?在您之前尝试过的同一个 __init__.py 中,使用以下内容:

import gettext
gettext.install('brainz', '../datas/translations/')

就是这样! 项目范围 _() 使用标准 gettext 模块,以一种公开、优雅且方便的方式实现可用性。但是,公平地说,如果您查看 gettext 的源代码,您会发现它使用了 Elf 建议的相同技巧。所以,本质上,这也是纯粹的邪恶(tm)。但是,如果“brainz”模块仅由您的应用程序使用并且不打算由其他应用程序导入,那么这完全没问题。

如果你想与其他应用程序共享'brainz',你应该使用sdolan的方法:在每个模块中导入它。但是,我再次建议,不要像您那样使用 bindtextdomaintextdomain

import gettext
t = gettext.translation('brainz', '../datas/translations/')
_ = t.ugettext

区别在于使用 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:

import gettext
gettext.install('brainz', '../datas/translations/')

And that's it! Project-wide _() availability, in a non-cryptic, elegant and convenient way, using the standard gettext 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 and textdomain like you did, I suggest this:

import gettext
t = gettext.translation('brainz', '../datas/translations/')
_ = t.ugettext

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's xgettext. Don't! Pygettext is extremely outdated and lacks several features. xgettext is much more powerful and flexible, and fully supports Python.

故事和酒 2024-10-03 06:33:21

通配符导入不会导入以下划线开头的任何内容。

通配符很糟糕,它们会污染命名空间,并产生难以发现的错误。此外,_ 有时用于表示未使用的变量。

只需在需要的地方进行导入即可。它只有一行,因此输入并不困难,而且您始终可以在 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.

潇烟暮雨 2024-10-03 06:33:21

这是纯粹的邪恶,但它却能如你所愿。在项目的 _init.py_ 根目录中,执行以下操作:

from django.utils.translation import ugettext
import __builtin__
__builtin__.__dict__['_'] = ugettext

现在下划线到处都是 ugettext。其他答案有适当的警告;修改 python VM 的内置列表并不是很好,而且它肯定会让任何不熟悉它的人感到困惑。

This is pure evil, but it does what you want. In the _init.py_ root of your project, do this:

from django.utils.translation import ugettext
import __builtin__
__builtin__.__dict__['_'] = ugettext

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文