Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

multi language support in python script

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

like image 925
otmezger Avatar asked Dec 26 '22 14:12

otmezger


2 Answers

see python gettext module for i18n support

like image 147
Guy Gavriely Avatar answered Dec 28 '22 04:12

Guy Gavriely


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

like image 39
LightWing Avatar answered Dec 28 '22 03:12

LightWing