8

I have a large python (2.7) script that reads data from a database and generate pictures in pdf format. My pictures have strings for labels, etc...

Now I want to add a multi language support for the script, so I can generate the same pictures in different languages by passing a variable to my script.

I was thinking in having a class with all the strings and their translations in a dictionary. For example:

Strings['string1'] = {'de':'string in german', 'en': 'string in english'}

I could acces the strings with

my_needed_string = 'string1'
selected_language = 'en'
Strings[my_needed_string][selected_language]

is there a better, more professional way to do this? with "better" I mean more flexible and easier to maintain? I have at least 80 different strings in 2 or more languages.

Thanks

3
  • 1
    How many different strings do you have? If it is a few specific strings, then it shouldn't be a problem. Otherwise take a look at gettex. Commented Jan 22, 2014 at 0:20
  • I will have at least 80 strings, and maybe we implement a third language Commented Jan 22, 2014 at 0:36
  • In that case it probably wouldn't be a good idea to do it manually... Commented Jan 22, 2014 at 0:39

4 Answers 4

11

see python gettext module for i18n support

Sign up to request clarification or add additional context in comments.

3 Comments

+1. For a simple case like this, gettext is probably enough. For a case where it's not, you usually want to use tools like babel, i18n, etc. (search PyPI) that either build on top of or emulate gettext, so it's still usually a good place to start.
I read the documentation of gettext and I was thinking it is too big for my needs... maybe I misunderstood it totally.
well, the idea is simple, you write all your strings in English and wrap them with _() then you can add as many languages as you want while keeping extra languages strings in separate files outside of your source code, I guess you know your needs better then us, its just a suggestion...
5

If you only have a few languages, and don't want to use some i18n stuff, try one of these:

example (I'm just using a dict in a py file, let me know if you want specifically json):

also, this is written in python 3, not 2.

in en.py

en = {
    "eng": "english",
    "heb": "hebrew",
    "menu": {
        "menu1": "one",
        "menu2": "two"
    }
}

in he.py

he = {
    "eng": "אנגלית",
    "heb": "עברית",
    "menu": {
        "menu1": "אחד",
        "menu2": "שתיים"
    }
}

option 1 using SimpleNamespace:

from types import SimpleNamespace

#import language dicts from which ever folder and file they are, for me its the same folder and different files...
from .he import he
from .en import en

class NestedNamespace(SimpleNamespace):
    def __init__(self, dictionary, **kwargs):
        super().__init__(**kwargs)
        for key, value in dictionary.items():
            if isinstance(value, dict):
                self.__setattr__(key, NestedNamespace(value))
            else:
                self.__setattr__(key, value)

text = {}
text.update({"he": NestedNamespace(he)})
text.update({"en": NestedNamespace(en)})
print(text['he'].menu.menu1) #works

option 2 using namedtuple (i think this one is slower, by what i read about the way namedtuples are made, but im no pro, so choose whatever you like):

from collections import namedtuple

def customDictDecoder(dict1):
    for key, value in dict1.items():
        if type(value) is dict:
            dict1[key] = customDictDecoder(value)
    return namedtuple('X', dict1.keys())(*dict1.values())

text = {}
text.update({"he": customDictDecoder(he)})
text.update({"en": customDictDecoder(en)})
print(text['he'].menu.menu2) #works

if you want print(text.he.menu.menu1) to work, it is possible, but i dont see the use for it, if you want it, let me know

Comments

0

I had this problem a while ago and just solved it by creating two arrays with the words of the two languages I needed.

# array with english words
engList = ["dog", "cat"]
# array with german words
gerList = ["Hund", "Katze"]

Then I just set another array to the needed language array and use the words from this array.

# referenced array set to the english array
langList = engList

print(langList[0],"+",langList[1])

# change to the german array when needed
langList = gerList

print(langList[0],"+",langList[1])

Of course it's no way near to be perfect, but it worked for me. Hope I could help!

Comments

-1

A more 'pythonic way' could be if you just make a different .py and make a new class there with if statements for each language:

class Locale:
def __init__(self, loc):
    if loc == "en":
        self.string = "something in English"
    elif loc == "fr":
        self.string = "something in French"

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.