Писать два класса в отдельные файлы, которые конвертируются друг в друга?

Допустим, у меня есть два файла, в каждом из которых есть класс. int.py, который имеет настраиваемую реализацию целочисленного класса, и float.py, который имеет настраиваемую реализацию класса с плавающей запятой.

Я хочу, чтобы у каждого класса был метод преобразования в другой. Например:

class Integer:   
  def __init__(self, value):
    self.value = value

  def to_f():
    return Float(self.value)

а также

class Float:   
  def __init__(self, value):
    self.value = value

  def to_i():
    return Integer(self.value)

Как я могу импортировать файлы друг в друга, чтобы конструкторы были доступны, не вызывая циклической зависимости?


person Cisplatin    schedule 18.05.2017    source источник
comment
Поместите их в один файл - вы можете столкнуться с проблемами циклического импорта.   -  person inspectorG4dget    schedule 18.05.2017


Ответы (2)


Вы можете импортировать класс при вызове метода:

class Float:   
  def __init__(self, value):
    self.value = value

  def to_i(self):
    from integer import Integer
    return Integer(self.value)

Импорт кэшируется в sys.modules, поэтому он не будет иметь никакого снижения производительности, кроме первого вызова Float.to_i.


Альтернативой является импорт самого модуля и поиск класса:

import integer

class Float:   
  def __init__(self, value):
    self.value = value

  def to_i(self):
    return integer.Integer(self.value)

Пока нет циклических зависимостей на уровне модуля (например, подкласс Float в integer), у вас не будет никаких проблем.


Еще одна (потенциально сбивающая с толку) альтернатива - импортировать классы после модулей:

class Float:   
  def __init__(self, value):
    self.value = value

  def to_i(self):
    return Integer(self.value)


from integer import Integer

К тому времени, когда будет вызван Float.to_i, Integer будет в области действия. Я только помню, как видел первые два метода, используемых в реальном коде.

person Blender    schedule 18.05.2017

Просто импортируйте классы локально:

class Float:  
  def to_i():
    from .int import Integer  # not run at module loading time
    return Integer(self.value)

class Integer:   
  def to_f():
    from .float import Float
    return Float(self.value)

Это предотвращает запуск импорта во время загрузки модуля и, таким образом, позволяет избежать циклического импорта.

person schwobaseggl    schedule 18.05.2017