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?
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?
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?
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?
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?
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
Re: variable declaration
On Dé Máirt, Feabh 1, 2005, at 12:19 America/Chicago, Alex Martelli wrote: Michael Tobis <[EMAIL PROTECTED]> wrote: ... I don't know that it's ever necessary to rebind, but it is, in fact, common, and perhaps too easy. In numeric Python, avoiding rebinding turns out to be a nontrivial skill. Well, a for-statement is BASED on rebinding, for example. Maybe you don't mean to address rebinding per se, but rebinding in ``separate statements''? The ``separation'' needs to be defined carefully to make while-loops work, too. Normally, a while-statement's header clause would be something like: while : where the expression depends on the values bound to some local variables. For the first evaluation, the variables need to be bound by earlier statements; for the expression to eventually become false, it's likely (unless we're talking about mutable objects) that the variables need to be re-bound in the loop body. For example, consider: def f(a, b): x = 0 while x < 10: print x, x = a*x + b print I think you guys are talking about rebinding of quite different objects. Rebinding x in the above example is not what Michael Tobis is talking about, I presume, though x is prone to the 'epselon' error. But, C'est la vie. If x was some sort of counter (time step, iteration) and there was a Numeric array y to be processed in that loop, def f(a, b): y = Numeric.zeros((100, 100), 'd') x = 0 while x < 10: x = a*x + b y = a*y + b it is actually important (e.g. in terms of performance) not to rebind y. Okay, in this case it is straightforward to change function f to function g, so that y does not get recreated (rebound). def g(a, b): y = Numeric.zeros((100, 100), 'd') x = 0 while x < 10: x = a*x + b y *= a y += b I don't know if y gets 'rebound' in a strict sense of the word. But y does not call it's constructor (which is expensive). And in terms of performance y = Numeric.zeros((100, 100), 'd') 10.0100.010 574.050 574.050 profile:0(f(1,1)) 1 -0.000 -0.000 416.640 416.640 profile:0(g(1,1)) y = numarray.zeros((100, 100), 'd') 10.0200.020 231.359 231.359 profile:0(f(1,1)) 10.0100.010 27.899 27.899 profile:0(g(1,1)) it's quite a difference. would you require the programmer to find out a closed-form expression for this recurrence relation, in order to avoid having to rebind the name 'x'? OK, in this particular case it may be OK, if you are willing Using Numeric arrays or Numarrays, it might help to have some closed-form expression for the above (I'm quite sure there is, see daxpy in BLAS). But then, I'd say it's in the responsability of the programmer who did class Y to create y to prevent the user from using y = a*y + b. Either in the documentation or really strictly by not implementing + and * (only =+ and =*). This kind of restriction/declaration should not be in Python, but in the module that provides Y. to put competence in college-level algebra as a prerequisite for using Python. But what if the rebinding in the body of the loop was to a more I believe those using Numeric/Numarray might have heard of algebra and in-place operations. So, one could even argue that it's up to the user to find an efficient way to avoid rebinding of y. Christian -- http://mail.python.org/mailman/listinfo/python-list
Re: Finding user's home dir
On Dé Céadaoin, Feabh 2, 2005, at 13:26 America/Chicago, Nemesis wrote: Hi all, I'm trying to write a multiplatform function that tries to return the actual user home directory. I saw that Please, could you test it on your systems and tell me what you got? I'd like to know what it returns on different operating systems because I'm developing a multiplatform software. It works with Python 2.2 and Python 2.3 on Mac OS 10.2 and Debian Linux. Christian -- http://mail.python.org/mailman/listinfo/python-list
Re: Reinstall python 2.3 on OSX 10.3.5?
On Dé Céadaoin, Feabh 2, 2005, at 17:48 America/Chicago, [EMAIL PROTECTED] wrote: Hi there I started a very long and roundabout process of attempting to install python 2.3.4 along side my apple-installed 2.3 system. To make a long story short, I have completely confabulated my environment ( i deleted the 2.3 binaries and so forth from the system in an attempt to start things fresh), and now I cannot figure out how to reinstall the base 2.3 Apple python distribution. Can somebody please point me in the right direction? You could use fink install python which makes you a Python installation under /sw. Christian -- http://mail.python.org/mailman/listinfo/python-list
Re: Reinstall python 2.3 on OSX 10.3.5?
On Déardaoin, Feabh 3, 2005, at 01:52 America/Chicago, Robert Kern wrote: Christian Dieterich wrote: On Dé Céadaoin, Feabh 2, 2005, at 17:48 America/Chicago, [EMAIL PROTECTED] wrote: Hi there I started a very long and roundabout process of attempting to install python 2.3.4 along side my apple-installed 2.3 system. To make a long story short, I have completely confabulated my environment ( i deleted the 2.3 binaries and so forth from the system in an attempt to start things fresh), and now I cannot figure out how to reinstall the base 2.3 Apple python distribution. Can somebody please point me in the right direction? You could use fink install python which makes you a Python installation under /sw. But that doesn't solve his problem, which is to restore the Apple-supplied Python that he deleted. Agreed. I was not aware that the preinstalled Python differs from a normal one. I implicitely assumed he would link /usr-Python to /sw-Python, and then continue using fink for not to interfere with /usr anymore. Christian -- http://mail.python.org/mailman/listinfo/python-list
Re: SysV IPC message queues
On Déardaoin, Feabh 3, 2005, at 02:29 America/Chicago, Aki Niimura wrote: Hello everyone. I'm trying to control a program from a Python program using IPC. Although using a socket is a common choice for such applications, I would like to use SysV message queues because I don't need to parse the stream. I thought Python had a support of SysV message queues (I have found almost anything I need in Python library modules so far). But Python library seems not supporting SysV message queues yet. I'm thinking of calling a C function from Python but it seems not so easy. Although this might not be the most elegant way to do what you want, it's relatively easy to make a C function work with Python. Have a look at http://www.swig.org/ Swig writes a C/Python wrapper for your C code which can be compiled into a shared object library. Then you can import that in Python. Swig is also (rudimentary) supported by distutils, so you don't even need to deal with the generation of the library. Christian Example: > cat src/SomeModule.i %module SomeModuleLib %{ #include "SomeModule.h" %} %include src/SomeModule.c > swig -python src/SomeModule.i > gcc -I/sw/include/python2.3 -c src/SomeModule.c -o SomeModule.o > gcc -I/sw/include/python2.3 -c src/SomeModule_wrap.c -o SomeModule_wrap.o > gcc -L/sw/lib -bundle -flat_namespace -undefined suppress SomeModule.o SomeModule_wrap.o -o _SomeModuleLib.so or automatic build from setup.py from distutils.core import setup, Extension import os, glob srcfiles = glob.glob(os.path.join('src', '*.[ci]')) setup(name="SomePackage", package_dir={"SomePackage": "lib"}, packages=["SomePackage"], ext_modules=[Extension("SomePackage._SomeModuleLib", srcfiles,),],) >>> import SomeModuleLib -- http://mail.python.org/mailman/listinfo/python-list
Re: Pickling and inheritance are making me hurt
On Dé hAoine, Feabh 4, 2005, at 15:48 America/Chicago, Kirk Strauser wrote: I have a module that defines a Search class and a SearchResult class. I use these classes by writing other modules that subclass both of them as needed to interface with particular search engines. My problem is that Search defines a method (called automatically by __del__) to save its results between invocations: def _saveresults(self): self._oldresults = self._results file = open(self._storefile(), 'w') pickle.dump(self._oldresults, file) file.close() The problem I'm having is the the pickle.dump call is failing whenever the objects in "self.data" are instances of derivatives of SearchResult rather than instances of SearchResult itself (which is pretty much always the case): Exception pickle.PicklingError: 0xb7f7ad6c> in 0xb7ec954c>> ignored Now, if I overload _saveresults inside a subclass of Search, then it works. It seems like the problem is that _saveresults is only looking inside the same namespace as Search (where it's originally defined), even if it's actually been inherited by another class in a different module. Is there a way around this? It's hard to tell exactly what's going on. I have only suggestions what you could try to verify. There was a thread a few days ago, where it was concluded that garbage collecting happens in alphabetical order. Can't remember which one it was. You could temporarily rename self._result to self.z_result to check that. Here's a gotcha that I had in a similar context. Well, it's logical but somehow unexpected. If you do for example s = Search() s = Search() the calling sequence for the constructor and destructor is __init__() __init__() __del__() Maybe this interferes with pickling your first instance? Hope this helps debugging, Christian -- http://mail.python.org/mailman/listinfo/python-list
Re: Python-libnjb on macosx
On Déardaoin, Feabh 10, 2005, at 18:08 America/Chicago, Robert Kern wrote: Timothy Grant wrote: I was working on some things that use Glenn Strong's excellent libnjb wrapper on my Linux box. I have since bought a PowerBook and have been trying to get everything working correctly under OS/X. This morning I got Python-libnjb to build without errors using the following command: ld -dynamic -dylib -L/sw/lib -L/sw/lib/python2.3/config njb_c_wrap.o -o _njb_c.dylib -lpython2.3 -lnjb -lSystem -framework IOKit -ldylib1.o Try to write a distutils setup.py script. It should take care of the correct linker arguments for you. I (distutils) usually include -bundle -flat_namespace -undefined suppress to build .so files. Maybe this helps in your case too. But the setup.py is definitively the safer way. Christian -- http://mail.python.org/mailman/listinfo/python-list