using names before they're defined

Bruno Desthuilliers onurb at xiludom.gro
Wed Jul 19 12:13:44 EDT 2006


davehowey at f2s.com wrote:
> I have a problem. I'm writing a simulation program with a number of
> mechanical components represented as objects. When I create instances
> of objects, I need to reference (link) each object to the objects
> upstream and downstream of it, i.e.
> 
> supply = supply()

NB : Python convention is to use CamelCase for non-builtin types. FWIW,
the above line will rebind name 'supply', so it won't reference the
supply class anymore...

> compressor = compressor(downstream=combustor, upstream=supply)
> combuster = combuster(downstream=turbine, upstream=compressor)
> etc.
> 
> the problem with this is that I reference 'combustor' before is it
> created. If I swap the 2nd and 3rd lines I get the same problem
> (compressor is referenced before creation).
> 
> 
> aargh!!! any ideas on getting around this?

Solution 1: do a two-stages initialisation


supply = Supply()
compressor = Compressor()
combuster = Combuster()
turbine = Turbine()

compressor.chain(downstream=combustor, upstream=supply)
combuster.chain(downstream=turbine, upstream=compressor)

etc...

Tedious and error-prone... Unless you use a conf file describing the
chain and a function building it, so you're sure the 2-stage init is
correctly done.


Solution 2: 'implicit' chaining

if I understand the problem correctly, your objects are chained, ie:
supply <- compressor <- combuster <- turbine...

If yes, what about:

class Chainable(object):
  def __init__(self, upstream):
    self.upstream = upstream
    if upstream is not None:
      upstream.downstream = self

class Supply(Chainable):
  #

# etc

then:

supply = Supply()
compressor = Compressor(upstream=supply)
combuster = Combuster(upstream=compressor)
turbine = Turbine(upstream=combuster)


Or if you don't need to keep direct references to all elements of the chain:


class Chainable(object):
  def __init__(self, downstream=None):
    self.downstream = downstream
    if downstream is not None:
       downstream.upstream = self


supply = Supply(
  downstream=Compressor(
    downstream=Combuster(
     downstream=Turbine()
    )
  )
)

or more simply:
supply = Supply(Compressor(Combuster(Turbine())))


FWIW, you could then make Chainable class an iterable, allowing:
for item in supply:
  # will yield supply, then compressor, then combuster, then turbine
but I don't know if it makes any sens wrt/ your app !-)

Now there can of course be a lot of other solutions...

-- 
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in 'onurb at xiludom.gro'.split('@')])"



More information about the Python-list mailing list