2015-04-28 3 views
0

Фон:Python - Динамически инициализировать класс на основе параметра

Я работаю на довольно большой приложение, которое было HARDCODED строк на всем ее протяжении. Пришло время, когда приложение нужно было локализовать и перевести. В этот момент все (или почти все) жестко закодированные строки были перемещены в класс с соответствующим именем с параметрами для строк.

Что мне нужно сделать:

То, что я пытаюсь сделать, это все эти объекты строки класса расширить базовый класс. Внутри этого базового класса я хватаю языковой стандарт по умолчанию ОС и хочу загрузить соответствующий локализованный класс в другую папку.

То, что я до сих пор:

Пример Строка Class - Имя файла HeaderStrings.py

class TabLabels(BaseLanguageClass): 
    label_one = 'Label 1' 
    label_two = 'Label 2' 
    label_three = 'Label 3' 

BaseLanguageClass

class BaseLanguageClass(object): 
    def __init__(self, os_locale=None): 
     if os_locale is None: 
      os_locale = locale.getdefaultlocale()[0] 
     if os_locale == 'en_US': 
      pass # Do nothing and just initialize the called class 
     else: 
      # Gets set to TabLabels 
      string_class = str(self.___class__.__name__) 

      # Gets set to HeaderStrings 
      file_path = str(inspect.getfile(self.__class__)).split('\\')[-1].split('.')[0] 

      try: 
       object_i_want = getattr(__import__("path.to.l10n.classes.%s.%s" % (os_locale, file_path), 
                fromlist=[string_class]), string_class)() 
      except: 
       pass 

object_i_want правильно получает локализованное класс, который я необходимость. Однако мне нужно вернуть это вместо фактического вызова. Если импорт завершается неудачно, он просто возвращает вызываемого. Я попытался присвоить object_i_want себе, но я знаю, что это не сработает, но я попробовал это из отчаяния.

Если я:

var = TabLabels(os_locale='fr').label_one, переступая через него правильно получает французский класс для object_i_want, но вар заканчивает тем, что экземпляр исходных TabLables вместо fr.TabLabels

Что у меня есть вероятно, крайне хакерский, и я надеюсь, что есть лучший способ сделать это, не рефакторируя около 2000 файлов. Приветствуется всяческая помощь.

+0

Это звучит так, как будто вы достаточно далеко вперед, но вы думали об использовании [Gettext] (https://docs.python.org/3.3/library/gettext.html) библиотека Питона? Это, безусловно, заставило вас не изобретать колесо ... –

+0

Переключение на что-то вроде gettext было бы оптимальным в долгосрочной перспективе, и у меня есть это в моем «хорошем, чтобы иметь» список, чтобы идти по этому маршруту. Но, к сожалению, непосредственные потребности программного обеспечения перевешивают преимущества выделения ресурсов на этот объем рефакторинга. – user1919655

+0

Понял. Я так много думал, но думал, что выброшу его там, если бы мысль не возникла. К сожалению, кроме того, у меня ничего нет на этом. –

ответ

0

После небольшого количества игр с этим я решил, что лучший способ сделать это - использовать __new__ для фактического переназначения объекта класса, который я хочу.

К сожалению, другие мои коллеги ссылались на статические переменные непосредственно, а не на создание нового экземпляра класса (TabLabels.label_one против TabLabels().label_one). Поэтому в конце концов требуется много рефакторинга. Если у кого-то нет такого решения.

class BaseLanguageClass(object): 
    def __new__(self, os_locale=None): 
     if os_locale is None: 
      os_locale = locale.getdefaultlocale()[0] 
     if os_locale == 'en_US': 
      return self 
     else: 
      # Gets set to TabLabels 
      string_class = str(self).split('\\')[0].split('.')[-1].split('\'')[0] 

      # Gets set to HeaderStrings 
      file_path = str(self).split('\\')[0].split('.')[-2] 

      try: 
       return getattr(__import__("path.to.l10n.classes.%s.%s" % (os_locale, file_path), 
               fromlist=[string_class]), string_class) 
      except: 
       return self 
Смежные вопросы