Welcome, guest | Sign In | My Account | Store | Cart

In some code I have to work with but don't have much control over, there are a bunch of strings declared at the module level. I need to figure out what all those strings are, and wrap them in something. Once they are wrapped, they must behave as strings, but lazily "translate" themselves whenever used in order for internationalization to work. Since each Web request might request a different language, I can't just do this once and be done with it.

Python, 42 lines
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
"""Lazily translate strings declared as globals."""

from UserString import UserString


class LazyGettext(UserString, object):

    def get_data(self): 
        return self.translate(self.__data)

    def set_data(self, value):
        self.__data = value

    data = property(get_data, set_data, None,
        """UserString stores the underlying string here.

        I have a set method that accepts the untranslated string.  I have a get
        method that returns the translated version of the string.

        """)

    def translate(self, s):
        """This is just "sample code", but you get the idea."""
        print "What language would you like to translate s to?"
        return "%s: %s" % (raw_input(), s)

    def __mod__(self, arg):
        """Fix UserString.__mod__ which will fail here.

        Somehow, it evaluates the data twice.
        
        """
        s = self.data
        return s % arg 


# Initially:
module_string = "Hi, my name is %s"

# Later, from another module:
module_string = LazyGettext(module_string)
print module_string % "JJ"

This recipe works well when used in conjunction with the FooProxy recipe; use a proxy to get the thread-specific gettext.translation instance.