3

I'm building a class, Child, that inherits from another class, Parent. The Parent class has a loadPage method that the Child will use, except that the Child will need to run its own code near the end of the loadPage function but before the final statements of the function. I need to somehow insert this function into loadPage only for instances of Child, and not Parent. I was thinking of putting a customFunc parameter into loadPage and have it default to None for Parent, but have it default to someFunction for Child.

How do I change the defaults for the loadPage method only for instances of Child? Or am I going about this wrong? I feel like I may be overlooking a better solution.

class Parent():
    def __init__(self):
        # statement...
        # statement...
    def loadPage(self, pageTitle, customFunc=None):
        # statement...
        # statement...
        # statement...
        if customFunc:
            customFunc()
        # statement...
        # statement...

class Child(Parent):
    def __init__(self):
        Parent.__init__(self)
        self.loadPage.func_defaults = (self.someFunction)  #<-- This doesn't work
Simon Lehmann
  • 10,737
  • 4
  • 41
  • 53
Tanner Semerad
  • 12,472
  • 12
  • 40
  • 49

5 Answers5

4

For such things, I do it in a different way :

class Parent():
   def loadPage(self, pageTitle):
      # do stuff
      self.customFunc()
      # do other stuff

   def customFunc(self):
      pass

class Child(Parent):

   def customFunc(self):
      # do the child stuff

then, a Child instance would do the stuff in customFunc while the Parent instance would do the "standard" stuff.

Cédric Julien
  • 78,516
  • 15
  • 127
  • 132
  • 1
    you could even check the existance of customFunc using `hasattr(self, 'customFunc')` before calling it, thus avoiding defining it in the parent class. – Alexis Métaireau Aug 17 '11 at 22:07
  • 2
    @Alexis Métaireau : yes, or a `try: except AttributeError` statement around the call to the method, but defining an empty method keep code simple IMHO ;) – Cédric Julien Aug 17 '11 at 22:11
  • 2
    Ah, we had the same thought. +1. @Alexis Métaireau, true, but I don't think it's quite as clean that way. Plus, to me, the need for a `custom_func` of this kind in one descendent suggests that an appropriately abstract base class should have the function too. – senderle Aug 17 '11 at 22:11
  • 1
    @Alexis Métaireau Wouldn't this make the implementation of the caller less clear and doesn't really save you anything? (`if hasattr(self, 'customFunc'):` needs even more characters than `def customFunc(self): pass` – Simon Lehmann Aug 17 '11 at 22:13
  • This assumes you never want to override the class' customFunc, as the OP seems to intend to allow. That said, it might not be a good idea to allow that. – Karl Knechtel Aug 17 '11 at 22:18
  • 1
    This "different way" is known as the object-oriented way. – martineau Aug 17 '11 at 23:25
  • Thanks for the quick response. It works perfectly. I knew I was overthinking it – Tanner Semerad Aug 18 '11 at 19:39
2

Modifying your method as little as possible:

class Parent(object):
    def __init__(self):
        pass
    def loadPage(self, pageTitle, customFunc=None):
        print 'pageTitle', pageTitle
        if customFunc:
            customFunc()

class Child(Parent):
    def __init__(self):
        Parent.__init__(self)
    def loadPage(self, pagetitle, customFunc = None):
        customFunc = self.someFunction if customFunc is None else customFunc
        super(Child, self).loadPage(pagetitle, customFunc)
    def someFunction(self):
        print 'someFunction'


p = Parent()
p.loadPage('parent')
c = Child()
c.loadPage('child')
agf
  • 171,228
  • 44
  • 289
  • 238
2

I wouldn't try to do this with defaults. Straightforward class inheritance already provides what you need.

class Parent():
    def __init__(self):
        # statement...
        # statement...

    def loadPage(self, pageTitle):
        # ... #
        self.custom_method()
        # ... #

    def custom_method(self):
        pass # or something suitably abstract

class Child(Parent):
    def __init__(self):
        Parent.__init__(self)

    def custom_method(self):    
        # what the child should do do
senderle
  • 145,869
  • 36
  • 209
  • 233
0

Can the statements before the customFunc() call be exported to a function? and the same for the statements after this call.

If yes, then the parent class will just call these two functions, and the child class will have the customFunc() call between them. So only the calls will be duplicated.

I may be overlooking a better solution.

Anis Abboud
  • 1,328
  • 2
  • 16
  • 23
0

Well, the best is probably to rely on an internal attribute, so you would have something like this:

class Parent(object):
    def __init__(self):
        self._custom_func = None
    def load_page(self, page_title):
        if self._custom_func:
            self._custom_func()

class Child(Parent):
    def __init__(self):
        super(Parent, self).__init__()
        self._load_page = some_function
Alexis Métaireau
  • 10,767
  • 5
  • 24
  • 34