inherit without calling parent class constructor?

Discussion in 'Python' started by Christian Dieterich, Jan 26, 2005.

  1. Hi,

    I need to create many instances of a class D that inherits from a class
    B. Since the constructor of B is expensive I'd like to execute it only
    if it's really unavoidable. Below is an example and two workarounds,
    but I feel they are not really good solutions. Does somebody have any
    ideas how to inherit the data attributes and the methods of a class
    without calling it's constructor over and over again?

    Thank,

    Christian

    Here's the "proper" example:

    class B:
    def __init__(self, length):
    size = self.method(length)
    self.size = size
    def __str__(self):
    return 'object size = ' + str(self.size)
    def method(self, length):
    print 'some expensive calculation'
    return length

    class D(B):
    def __init__(self, length):
    B.__init__(self, length)
    self.value = 1

    if __name__ == "__main__":
    obj = D(7)
    obj = D(7)

    Here's a workaround:

    class B:
    def __init__(self, length):
    size = self.method(length)
    self.size = size
    def __str__(self):
    return 'object size = ' + str(self.size)
    def method(self, length):
    print 'some expensive calculation'
    return length

    class D(B):
    def __init__(self, object):
    for key, value in object.__dict__.iteritems():
    setattr(self, key, value)
    self.value = 1

    if __name__ == "__main__":
    tmp = B(7)
    obj = D(tmp)
    obj = D(tmp)

    Here's another workaround:

    Bsize = 0
    class B:
    def __init__(self, length):
    size = self.method(length)
    self.size = size
    global Bsize
    Bsize = self.size
    def __str__(self):
    return 'object size = ' + str(self.size)
    def method(self, length):
    print 'some expensive calculation'
    return length

    class D(B):
    def __init__(self, length):
    self.size = Bsize
    self.value = 1

    if __name__ == "__main__":
    B(7)
    obj = D(9)
    obj = D(9)
    Christian Dieterich, Jan 26, 2005
    #1
    1. Advertising

  2. Christian Dieterich wrote:
    > Hi,
    >
    > I need to create many instances of a class D that inherits from a class
    > B. Since the constructor of B is expensive I'd like to execute it only
    > if it's really unavoidable. Below is an example and two workarounds, but
    > I feel they are not really good solutions. Does somebody have any ideas
    > how to inherit the data attributes and the methods of a class without
    > calling it's constructor over and over again?
    >
    > Thank,
    >
    > Christian
    >
    > Here's the "proper" example:
    >
    > class B:
    > def __init__(self, length):
    > size = self.method(length)
    > self.size = size
    > def __str__(self):
    > return 'object size = ' + str(self.size)
    > def method(self, length):
    > print 'some expensive calculation'
    > return length
    >
    > class D(B):
    > def __init__(self, length):
    > B.__init__(self, length)
    > self.value = 1
    >
    > if __name__ == "__main__":
    > obj = D(7)
    > obj = D(7)


    I'm confused as to how you can tell when it's avoidable... Do you mean
    you don't want to call 'method' if you don't have to? Could you make
    size a property, e.g.

    class B(object):
    def __init__(self, length):
    self._length = length
    def _get_size(self):
    print 'some expensive calculation'
    return self._length
    size = property(fget=_get_size)

    class D(B):
    def __init__(self, length):
    super(B, self).__init__(length)
    self.value = 1

    if __name__ == "__main__":
    obj = D(7)
    obj = D(7)

    Then 'size' won't be calculated until you actually use it. If 'size' is
    only to be calculated once, you might also look at Scott David Daniels's
    lazy property recipe:

    http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/363602

    Steve
    Steven Bethard, Jan 26, 2005
    #2
    1. Advertising

  3. Christian Dieterich wrote:
    > I need to create many instances of a class D that inherits from a class
    > B. Since the constructor of B is expensive I'd like to execute it only
    > if it's really unavoidable. Below is an example and two workarounds, but
    > I feel they are not really good solutions. Does somebody have any ideas
    > how to inherit the data attributes and the methods of a class without
    > calling it's constructor over and over again?


    - rename B to A
    - class B (A)
    - move the costly constructor from A to B
    - class D (A)

    You can now move some parts from B.__init__ to A.__init__ if they are
    really needed by D as well.

    In OO speak: D is not really a subclass of B. Refactor the common code
    into a new class A.

    Daniel
    Daniel Dittmar, Jan 26, 2005
    #3
  4. Christian Dieterich

    Jeff Shannon Guest

    Christian Dieterich wrote:

    > Hi,
    >
    > I need to create many instances of a class D that inherits from a class
    > B. Since the constructor of B is expensive I'd like to execute it only
    > if it's really unavoidable. Below is an example and two workarounds, but
    > I feel they are not really good solutions. Does somebody have any ideas
    > how to inherit the data attributes and the methods of a class without
    > calling it's constructor over and over again?


    You could try making D a container for B instead of a subclass:

    class D(object):
    def __init__(self, ...):
    self._B = None
    def __getattr__(self, attr):
    if self._B is None:
    self._B = B()
    return getattr(self._B, attr)

    Include something similar for __setattr__(), and you should be in
    business.

    If it will work for numerous D instances to share a single B instance
    (as one of your workarounds suggests), then you can give D's
    __init__() a B parameter that defaults to None.

    Jeff Shannon
    Technician/Programmer
    Credit International
    Jeff Shannon, Jan 26, 2005
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. pantalaimon
    Replies:
    3
    Views:
    51,034
    John Harrison
    Oct 9, 2004
  2. Christian Dieterich
    Replies:
    1
    Views:
    377
    Steven Bethard
    Jan 26, 2005
  3. Christian Dieterich
    Replies:
    1
    Views:
    349
    Steven Bethard
    Jan 26, 2005
  4. ali
    Replies:
    4
    Views:
    559
    David Harmon
    Mar 5, 2007
  5. Generic Usenet Account
    Replies:
    10
    Views:
    2,202
Loading...

Share This Page