inherit without calling parent class constructor?

  • Thread starter Christian Dieterich
  • Start date
C

Christian Dieterich

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)
 
S

Steven Bethard

Christian said:
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
 
D

Daniel Dittmar

Christian said:
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
 
J

Jeff Shannon

Christian said:
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
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,576
Members
45,054
Latest member
LucyCarper

Latest Threads

Top