I'm writing a Python3.x framework that has generators and filters. I have a compact syntax for chaining the output of generators and filters into filters, but file organization feels inelegant. Here's what I mean.
Assume Renderer is the super class for both generators and filters:
# file: renderer.py -- defines the common superclass used by generators and filters
class Renderer(object):
def render():
# Every subclass provides a `render` function that emits some data...
pass
# file: gen1.py -- defines a generator
class Gen1(Renderer):
def __init__(self):
super(Gen1, self).__init__()
def render(self):
... emit some data
# file: filt1.py -- defines a filter that takes any Renderer object as an input
class Filt1(Renderer):
def __init__(self, input, param):
super(Filt1, self).__init__()
self._input = input
self._param = param
def render():
... call self._input.render() to fetch and act on data before emitting it
# file: filt2.py -- defines a filter that takes any Renderer object as an input
class Filt2(Renderer):
def __init__(self, input):
super(Filt2, self).__init__()
self._input = input
def render():
... call self._input.render() to fetch and act on data before emitting it
# file: render_module.py -- a module file to bring in all the components
from renderer.py import Renderer
from gen1.py import Gen1
from filt1.py import Filt1
from filt2.py import Filt2
What I'd like
What I'd like is for a user of the platform to be able to write code like this, which chains the output of gen1
into filt1
, and the output of filt1
into filt2
:
import render_module as rm
chain = rm.Gen1().filt1(123).filt2()
chain.render()
What I've done
What I've done is add the following to renderer.py. This works, but see "The Problem to Solve" below.
class Renderer(object):
def render():
# emit some data...
pass
def filt1(self, param):
return rm.Filt1(self, parm)
def filt2(self):
return rm.Filt1(self)
import render_module as rm # at end of file to avoid a circular dependency
The Problem to Solve
It feels wrong to pollute the common superclass with specific mentions of each subclass. The clear indication of code smell is the import
statement at the end of renerer.py
.
But I haven't figured out a better way to refactor and organize the files. What's the pythonic approach out of this conundrum?