Re: inherit without calling parent class constructor?
On Dé Céadaoin, Ean 26, 2005, at 17:02 America/Chicago, Steven Bethard wrote: Just a note of clarification: The @deco syntax is called *decorator* syntax. Classes with a __get__ method are called *descriptors*. Okay, I think I get the idea. I didn't know about the @deco syntax, but it seems to be straightforward. And I got myself updated a little bit on descriptors and static methods. On Dé Céadaoin, Ean 26, 2005, at 17:09 America/Chicago, Jeff Shannon wrote: You could try making D a container for B instead of a subclass: Thank you for the solution. I'll need to have a closer look at it. However it seems like the decision whether to do some expensive calculation or not is delegated to the exterior of class D. Different classes that instanciate D would need to know what has been going on elsewhere. That might complicate things. I'll go ahead and try with the descriptors first. Thanks for all the help, Christian -- http://mail.python.org/mailman/listinfo/python-list
Re: inherit without calling parent class constructor?
Christian Dieterich wrote: On Dé Céadaoin, Ean 26, 2005, at 17:09 America/Chicago, Jeff Shannon wrote: You could try making D a container for B instead of a subclass: Thank you for the solution. I'll need to have a closer look at it. However it seems like the decision whether to do some expensive calculation or not is delegated to the exterior of class D. Different classes that instanciate D would need to know what has been going on elsewhere. That might complicate things. True, in the sense that B is instantiated as soon as a message is sent to D that requires B's assistance to answer. If the decision is a case of only calculate this if we actually want to use it, then this lazy-container approach works well. If the decision requires consideration of other factors, then it's a bit more complex -- though one could write that logic into D, and have D throw an exception (or return a sentinel) if it decides not to instantiate B at that time. This then requires a bit more checking on the client side, but the actual logic is encapsulated in D. And really, I don't see where the container approach shifts the decision any more than the descriptor approach does. In either case, the calculation happens as soon as someone requests D.size ... (However, from your other descriptions of your problem, it does sound like a property / descriptor is a better conceptual fit than a contained class is. I mostly wanted to point out that there are other ways to use OO than inheritance...) Jeff Shannon Technician/Programmer Credit International -- http://mail.python.org/mailman/listinfo/python-list
Re: inherit without calling parent class constructor?
On Déardaoin, Ean 27, 2005, at 14:05 America/Chicago, Jeff Shannon wrote: True, in the sense that B is instantiated as soon as a message is sent to D that requires B's assistance to answer. If the decision is a case of only calculate this if we actually want to use it, then this lazy-container approach works well. If the decision requires Yes, I see this advantage of a lazy container. Seems perfect to do something on request. See also below. the descriptor approach does. In either case, the calculation happens as soon as someone requests D.size ... Agreed. The calculation happens as soon as someone requests D.size. So far so good. Well, maybe I'm just not into it deep enough. As far as I can tell, In your class D the calculation happens for every instantiation of D, right? For my specific case, I'd like a construct that calculates D.size exactly once and uses the result for all subsequent instantiations. 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. This sounds as if B needs to instantiated only once. In your example self._B is None for every new instantiation of D and then __getattr__() makes a new instances of self.B. (However, from your other descriptions of your problem, it does sound like a property / descriptor is a better conceptual fit than a contained class is. I mostly wanted to point out that there are other ways to use OO than inheritance...) I appreciate your input anyway. Thinking of how I could use containers it became clear, that I'm going to use them for something else, where I want something to be calculated upon request only. Christian -- http://mail.python.org/mailman/listinfo/python-list
Re: inherit without calling parent class constructor?
Christian Dieterich wrote: On Déardaoin, Ean 27, 2005, at 14:05 America/Chicago, Jeff Shannon wrote: the descriptor approach does. In either case, the calculation happens as soon as someone requests D.size ... Agreed. The calculation happens as soon as someone requests D.size. So far so good. Well, maybe I'm just not into it deep enough. As far as I can tell, In your class D the calculation happens for every instantiation of D, right? For my specific case, I'd like a construct that calculates D.size exactly once and uses the result for all subsequent instantiations. Okay, so size (and the B object) is effectively a class attribute, rather than an instance attribute. You can do this explicitly -- class D(object): _B = None def __getattr__(self, attr): if self._B is None: if myB is None: myB = B() D._B = myB return getattr(self._B, attr) Now, when the B object is first needed, it's created (triggering that expensive calculation) and stored in D's class object. Since all instances of D share the class object, they'll all share the same instance of B. Probably not worth the trouble in this particular case, but maybe in another case... :) Jeff Shannon Technician/Programmer Credit International -- http://mail.python.org/mailman/listinfo/python-list
Re: inherit without calling parent class constructor?
On Déardaoin, Ean 27, 2005, at 19:25 America/Chicago, Jeff Shannon wrote: Okay, so size (and the B object) is effectively a class attribute, rather than an instance attribute. You can do this explicitly -- Ah, now I'm getting there. That does the trick. Probably not worth the trouble in this particular case, but maybe in another case... :) Yeah, maybe not. But I'll remember it as a useful recipe. Cheers, Christian -- http://mail.python.org/mailman/listinfo/python-list
inherit without calling parent class constructor?
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) -- http://mail.python.org/mailman/listinfo/python-list
Re: inherit without calling parent class constructor?
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 -- http://mail.python.org/mailman/listinfo/python-list
Re: inherit without calling parent class constructor?
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 -- http://mail.python.org/mailman/listinfo/python-list
Re: inherit without calling parent class constructor?
On Dé Céadaoin, Ean 26, 2005, at 11:46 America/Chicago, Steven Bethard wrote: 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. 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: On Dé Céadaoin, Ean 26, 2005, at 12:03 America/Chicago, Daniel Dittmar wrote: - 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. Thanks for the input. Yes, I see. I should have been more specific about 'when it's avoidable'. I guess this was part of my question: Is it avoidable? Steven, your solution works fine, as long as I don't access the size attribute. However, my instances of A use their size attributes quite often within other methods of A (not listed in my example). So, I'd just postpone the execution of the expensive part until later. Daniel, maybe I should have made it clearer in my example. The A-objects actually need the size attribute. If I'd outsource the size attribute (and its computation) to a class I don't inherit from, the A-objects won't have access to it. Or did I miss something in your solution? The size attribute only needs to be computed once and stays constant after that. The lazy property recipe of Scott David Daniels looks promising. I'll try that, when I've installed Python 2.4. However, I need my package to work on machines where there is Python 2.2 and 2.3 only. Thanks for more ideas, Christian -- http://mail.python.org/mailman/listinfo/python-list
Re: inherit without calling parent class constructor?
Christian Dieterich wrote: The size attribute only needs to be computed once and stays constant after that. The lazy property recipe of Scott David Daniels looks promising. I'll try that, when I've installed Python 2.4. However, I need my package to work on machines where there is Python 2.2 and 2.3 only. Note that: @deco def func(...): ... is basically just syntactic sugar for: def func(...): ... func = deco(func) So you don't need 2.4 to use the recipe; you just need a version of Python that supports descriptors (2.2 or later) since the recipe uses a class with __get__. I believe the following code should work for Python 2.2 and later, though I only have 2.4 to test it on at home. py class LazyAttribute(object): ... def __init__(self, calculate_function): ... self._calculate = calculate_function ... def __get__(self, obj, _=None): ... if obj is None: ... return self ... value = self._calculate(obj) ... setattr(obj, self._calculate.func_name, value) ... return value ... py class B(object): ... def __init__(self, length): ... self._length = length ... def size(self): ... print 'some expensive calculation' ... return self._length ... size = LazyAttribute(size) ... py class D(B): ... def __init__(self, length): ... super(D, self).__init__(length) ... self.value = 1 ... py b = B(5) py b.size some expensive calculation 5 py b.size 5 py d = D(6) py d.size some expensive calculation 6 py d.size 6 Note that b.size and d.size are only calculated once each, and if d.size is never accessed, you'll never incur the costs of calculating it. Steve -- http://mail.python.org/mailman/listinfo/python-list
Re: inherit without calling parent class constructor?
On Dé Céadaoin, Ean 26, 2005, at 13:45 America/Chicago, Steven Bethard wrote: Note that: @deco def func(...): ... is basically just syntactic sugar for: def func(...): ... func = deco(func) Oh, I learned something new today :-) Nice thing to know, these descriptors. Note that b.size and d.size are only calculated once each, and if d.size is never accessed, you'll never incur the costs of calculating it. That's exactly what I need. It works fine for Python 2.2 and 2.3. So, I'll try to implement that into my package. Thanks a bunch for your help, Christian -- http://mail.python.org/mailman/listinfo/python-list
Re: inherit without calling parent class constructor?
Christian Dieterich wrote: On Dé Céadaoin, Ean 26, 2005, at 13:45 America/Chicago, Steven Bethard wrote: Note that: @deco def func(...): ... is basically just syntactic sugar for: def func(...): ... func = deco(func) Oh, I learned something new today :-) Nice thing to know, these descriptors. Just a note of clarification: The @deco syntax is called *decorator* syntax. Classes with a __get__ method are called *descriptors*. But yes, they're both nice things to know. ;) Steve -- http://mail.python.org/mailman/listinfo/python-list
Re: inherit without calling parent class constructor?
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 -- http://mail.python.org/mailman/listinfo/python-list