On Sat, 29 Nov 2008, Carl Banks wrote: > On Nov 26, 11:20 pm, John O'Hagan <[EMAIL PROTECTED]> wrote: [...] > > > > class Bar(list): > > > > def __init__(self, a_bar, args, engine): > > list.__init__ (self, a_bar) > > self[:] = a_bar > > self.args = args > > self.engine = engine > > #more instance attributes... > > > > #methods... > > > > class Engine: > > > > def __init__(self, args): > > self.args = args > > #more instance attributes... > > > > def bar_builder(self): > > #body of method generates lists... > > yield Bar([generated_list], args, self) > > > > #more methods... > > > > #(other stuff...) > > > > def main(args): > > > > engine = Engine(args) > > bars = engine.bar_builder() > > for a_bar in bars: > > #play the music!... > > > > While this works (to my surprise!) and solves the problem which motivated > > it (i.e. Engine instances need to pass some attributes to Bar instances > > ), it seems too convoluted. Should one class inherit the other? > > No. (I wonder if you meant, "Should one class reference the other?", > as in, "Should Engines only reference bars or Bars only reference > engines, but not both?", in which case the answer is a non-commital, > "It depends.") > > Inheritance is not something you do because object A wants to access > the attributes/properties/etc. of B. Actually, that is something that > happens pretty often and when it does, there's a couple things you > should think about: > > 1. How you want A to access the attributes of B. Should you just let > A poke around in B, or should you define methods of B for A to call, > and those methods access the internals of B? It's a judgment call > most of the time. > > 2. Whether some behavior of B ought to be defined as part of A's class > instead, or vice versa. There is sometimes ambiguity over what class > a method that uses the attributes of two different objects should > belong to. > > Inheritance isn't something you need to think about here. > > Inheritance is something you consider when you have two objects, A and > B, that should act very similar or the same in certain situations. > Engines and Bars don't seem to share any behavior at all. Contrast > this to Bars and lists, which do share behavior. x[1] does pretty > much the same thing whether x is a Bar or a list, I'd imagine, so > there's reason for an inheritance relationship there. > > > If so, which way > > around? Or is it fine as is? > > One thing you might want to consider is whether Engine instance could > be simply passed into the Bar's play method (or whatever other method > accesses the Engine attributes), and whether the Engine needs to be > involved in generating bars at all. For instance: > > > class Bar(list): > def __init__(self, a_bar, args): > list.__init__(self, a_bar) > self[:] = a_bar > self.args = args > # etc. > def play(self, engine): > use(engine.time_signature).somehow() > # instead of use(self.engine.time_signature).somehow() > > > def bar_builder(self,args): > # plain function, not part of Engine class > # or perhaps a method of some other class > yield Bar([generated_list],args) > > > def main(): > engine = Engine(args) > bars = bar_builder(self,args) > for a_bar in bars: > a_bar.play(engine) > > > One benefit of doing it this way is that you've freed Bars and Engines > from each other. Conceivably you could create a second engine object > (maybe of a different type altogether), and play the very same Bar > objects with that engine instead.
Thanks for such a detailed reply...I actually had bar_builder as a plain function originally, but because I didn't know how to pass attributes around like you have above, I was using globals to do it and was trying to solve that by classing everything in sight. Although the program doesn't work quite as you have deduced above, I can use the approach you suggest to simplify it immensely. (I hope.) > > > I'm hoping this is a common trap I've fallen into; I just haven't been > > able to get my head around it. (I'm a musician...) > > Well I think it looks pretty good for a musician newbie. There's a > few organizational decisions I'd make differently, but overall it's > clean and readable and not too complicated how you did it. At least > not what you've showed us. :) > [...] Believe me, the whole thing is more complicated and messy, but you don't want to see my dirty laundry! :) Regards, john -- http://mail.python.org/mailman/listinfo/python-list