0

Let's say I have two files, each with a class in it. int.py, which has a custom implementation of an integer class, and float.py, which has a custom implementation of a float class.

I want each class to have a conversion method to the other. For example:

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

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

and

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

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

How can I import the files into each other so that the constructors are available, without causing a circular dependency?

Cisplatin
  • 2,860
  • 3
  • 36
  • 56

2 Answers2

2

You can import the class when the method is called:

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

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

Imports are cached in sys.modules, so it won't have any performance penalty beyond the first call to Float.to_i.


An alternative is to import the module itself and look up the class:

import integer

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

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

As long as there are no module-level circular dependencies (like subclassing Float in integer), you won't have any issues.


Yet another (potentially confusing) alternative is to import the classes after the modules:

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

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


from integer import Integer

By the time Float.to_i is called, Integer will be in scope. I only recall seeing the first two methods used in actual code.

Blender
  • 289,723
  • 53
  • 439
  • 496
0

Just import the classes locally:

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)

This prevents the imports from being run at module loading time and, thus, avoids circular imports.

user2390182
  • 72,016
  • 6
  • 67
  • 89