Question

The following program can run successfully:

class Simple(object):
    def __init__(self, name):
      self.name = name

    def __add__(self, other):
      c = Composite()
      c._members.append(self)
      c._members.append(other)
      return c

    def __repr__(self):
      return "Simple('%s')" % self.name

class Composite(object):
    def __init__(self):
      self._members = []

    def __add__(self, obj):
      if isinstance(obj, Simple):
        out = Composite()
        out._members = [k for k in self._members] + [obj]
      elif isinstance(obj, Composite):
        out = Composite()
        out._members = [k for k in self._members + obj._members]
      else:
        raise TypeError
      return out

if __name__ == "__main__":
    s1 = Simple('one')
    s2 = Simple('two')
    s3 = Simple('three')
    c1 = s1 + s2
    c2 = c1 + s3
    print c1._members
    print c2._members
    # output:
    # [Simple('one'), Simple('two')]
    # [Simple('one'), Simple('two'), Simple('three')]

I would like to keep the definition of Simple, Composite, and __main__ in three different files, but I cannot do it because I cannot import Simple into composite.py and I cannot import Composite into simple.py.

How would you modify the class definition such that you can keep separate files?

Thank you.

PS. I've read several answers related to "forward declaration" but could not find an answer to my specific problem.

Was it helpful?

Solution

Since none of the references are needed until the methods are called, circular imports can work here. The trick is to use fully-qualified references.

import composite

class Simple(object):
   ...
  def __add__(self, other):
    c = composite.Composite()
    c._members.append(self)
    c._members.append(other)
    return c

OTHER TIPS

The problem is that you get circular imports, right?

import Simple in the __add__ method instead of at the top of the file to avoid circular dependency. It will slow down the __add__ method somewhat, but usually not significantly.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top