3

I have a class which is derived from a base class, and have many many lines of code

e.g.

class AutoComplete(TextCtrl):
 .....

What I want to do is change the baseclass so that it works like

class AutoComplete(PriceCtrl):
 .....

I have use for both type of AutoCompletes and may be would like to add more base classes, so how can I do it dynamically?

Composition would have been a solution, but I do not want to modify code a lot.

any simple solutions?

asked Aug 26, 2009 at 12:02

3 Answers 3

7

You could have a factory for your classes:

def completefactory(baseclass):
 class AutoComplete(baseclass):
 pass
 return AutoComplete

And then use:

TextAutoComplete = completefactory(TextCtrl)
PriceAutoComplete = completefactory(PriceCtrl)

On the other hand depending on what you want to achieve and how your classes look, maybe AutoComplete is meant to be a mixin, so that you would define TextAutoComplete with:

class TextAutocomplete(TextCtrl, AutoComplete):
 pass
answered Aug 26, 2009 at 12:06
Sign up to request clarification or add additional context in comments.

4 Comments

I was thinking on similar lines, but it requires me to indent whole code, and as I said many many lines, objection looks trivial but I do wish I do not have to indent it
to not indent: Declare the classes hidden in the top level of the module as _TextAutoComplete and so on, then use the factory.
@Anurag, using vim in block mode, or sed, it's really easy to reindent (and you should learn how to do it, it's very useful when programming in python)
@tonfa thanks, I know how to indent code, but I just do not want to nest whole class code of 1000 lines 'Flat is better than nested.'
2

You could use multiple inheritance for this:

class AutoCompleteBase(object):
 # code for your class
 # remember to call base implementation with super:
 # super(AutoCompleteBase, self).some_method()
class TextAutoComplete(AutoCompleteBase, TextCtrl):
 pass
class PriceAutoComplete(AutoCompleteBase, PriceCtrl):
 pass

Also, there's the option of a metaclass:

class BasesToSeparateClassesMeta(type):
 """Metaclass to create a separate childclass for each base.
 NB: doesn't create a class but a list of classes."""
 def __new__(self, name, bases, dct):
 classes = []
 for base in bases:
 cls = type.__new__(self, name, (base,), dct)
 # Need to init explicitly because not returning a class
 type.__init__(cls, name, (base,), dct)
 classes.append(cls)
 return classes
class autocompletes(TextCtrl, PriceCtrl):
 __metaclass__ = BasesToSeparateClassesMeta
 # Rest of the code
TextAutoComplete, PriceAutoComplete = autocompletes

But I'd still suggest the class factory approach already suggested, one level of indentation really isn't that big of a deal.

answered Aug 26, 2009 at 14:53

Comments

1

You could modify the __bases__ tuple. For example you could add another baseclass:

AutoComplete.__bases__ += (PriceCtrl,)

But in general I would try to avoid such hacks, it quickly creates a terrible mess.

answered Aug 26, 2009 at 12:11

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.