From: Michael S. <m-s...@us...> - 2007-08-01 09:52:26
|
Salut, I have a problem with creating different instances of the pyx.document class: I would like to have a "slides" class which writes out a number of slides in different ways (for beamer presentations, for handouts, with different sizes). Unfortunately, when I create several pyx.document instances, they are all the same (having the same memory address)! See the enclosed minimal example. Is there an explanation for this behaviour? # ------------------------- from pyx import * class slides: def document(self): d = document.document() return d s = slides() for i in range(4): print s.document() # ------------------------- Michael. |
From: Andre W. <wo...@us...> - 2007-08-01 10:33:33
|
Hi Michael, still, you have different instances in your example. The only problem in your example is, that the garbage collector throws away the document instance immediately again. Check this out: from pyx import * class slides: def document(self): d = document.document() return d l = [] s = slides() for i in range(4): d = s.document() print d l.append(d) ... and you'll get diffent instances. Still, you may have some kind of a problem ... and there might be bugs. But as far as your example is concerned, everything is fine. Best, André On 01.08.07, Michael SCHINDLER wrote: > Salut, > > I have a problem with creating different instances of the pyx.document > class: I would like to have a "slides" class which writes out a number > of slides in different ways (for beamer presentations, for handouts, > with different sizes). > > Unfortunately, when I create several pyx.document instances, they are > all the same (having the same memory address)! See the enclosed > minimal example. Is there an explanation for this behaviour? > > # ------------------------- > from pyx import * > > class slides: > def document(self): > d = document.document() > return d > > s = slides() > for i in range(4): > print s.document() > # ------------------------- > > Michael. > > > ------------------------------------------------------------------------- > This SF.net email is sponsored by: Splunk Inc. > Still grepping through log files to find problems? Stop. > Now Search log events and configuration files using AJAX and a browser. > Download your FREE copy of Splunk now >> http://get.splunk.com/ > _______________________________________________ > PyX-user mailing list > PyX...@li... > https://lists.sourceforge.net/lists/listinfo/pyx-user André -- by _ _ _ Dr. André Wobst / \ \ / ) wo...@us..., http://www.wobsta.de/ / _ \ \/\/ / PyX - High quality PostScript and PDF figures (_/ \_)_/\_/ with Python & TeX: visit http://pyx.sourceforge.net/ |
From: Michael S. <m-s...@us...> - 2007-08-01 11:33:38
|
Salut André, On 01.08.07, Andre Wobst wrote: > still, you have different instances in your example. The only problem > in your example is, that the garbage collector throws away the > document instance immediately again. Check this out: > > from pyx import * > > class slides: > def document(self): > d = document.document() > return d > > l = [] > s = slides() > for i in range(4): > d = s.document() > print d > l.append(d) > > ... and you'll get diffent instances. Still, you may have some kind of > a problem ... and there might be bugs. But as far as your example is > concerned, everything is fine. You are right. That explains the equal memory addresses. I had, however the problem that upon writing the second document, the content of the first was still there. In the meanwhile, I found the reason for that: the dangerous initialization of empty lists: class document: def __init__(self, pages=[]): self.pages = pages The first use of this as document.document() and then adding some pages modifies the standard argument (which was [] initially). All further instances are then initialized with this nonempty list. Which solution do you prefer: class document: def __init__(self, pages=[]): self.pages = pages[:] class document: def __init__(self, pages=None): if pages is None: self.pages = [] else: self.pages = pages I will scan through the code to eliminate all other occurrences of this problem. Michael. -- Michael Schindler Laboratoire de Physico-Chimie Théorique. ESPCI. 10 rue Vauquelin, 75231 Paris cedex 05, France. Tel: +33 (0)1 40 79 45 97 Fax: +33 (0)1 40 79 47 31 http: www.pct.espci.fr/~michael |
From: Andre W. <wo...@us...> - 2007-08-01 11:56:51
|
Michael, On 01.08.07, Michael SCHINDLER wrote: > The first use of this as document.document() and then adding some > pages modifies the standard argument (which was [] initially). All > further instances are then initialized with this nonempty list. Blame on us. Blame ... please ... :-) > Which solution do you prefer: > > class document: > def __init__(self, pages=[]): > self.pages = pages[:] > > > class document: > def __init__(self, pages=None): > if pages is None: > self.pages = [] > else: > self.pages = pages I'm not sure. Personally I somehow favour the second option (which is quite Pythonic btw), but I remember a "bug" Jörg came up with some time ago. It was about an internal reordering of some attributes and it was done on the original list passed to the method. I understand that such a behaviour can be very troublesome and shouldn't be done for such an end-user library like PyX. So let me formulate a rule of thumb: Go for option 1 for all attributes, which are not read-only. (For read-only attribute *no* copy is necessary and should not be made.) Jörg, do you agree? > I will scan through the code to eliminate all other occurrences of > this problem. Thanks a lot! André -- by _ _ _ Dr. André Wobst / \ \ / ) wo...@us..., http://www.wobsta.de/ / _ \ \/\/ / PyX - High quality PostScript and PDF figures (_/ \_)_/\_/ with Python & TeX: visit http://pyx.sourceforge.net/ |
From: Michael S. <m-s...@us...> - 2007-08-01 12:45:17
|
André, On 01.08.07, Andre Wobst wrote: > > So let me formulate a rule of thumb: Go for option 1 for all > attributes, which are not read-only. (For read-only attribute *no* > copy is necessary and should not be made.) As it is easily possible in Python to overwrite data in instances (also ones that are not "self"), it is sometimes hard to see what is read-only. Especially in the graph module, complex use of foreign data is made -- can I rely on the assumption that foreign data is used read-only? Michael. -- Michael Schindler Laboratoire de Physico-Chimie Théorique. ESPCI. 10 rue Vauquelin, 75231 Paris cedex 05, France. Tel: +33 (0)1 40 79 45 97 Fax: +33 (0)1 40 79 47 31 http: www.pct.espci.fr/~michael |
From: Joerg L. <jo...@us...> - 2007-08-01 12:45:35
|
On 01.08.07, Andre Wobst wrote: > Michael, > > On 01.08.07, Michael SCHINDLER wrote: > > The first use of this as document.document() and then adding some > > pages modifies the standard argument (which was [] initially). All > > further instances are then initialized with this nonempty list. > > Blame on us. Blame ... please ... :-) Aii.... > > Which solution do you prefer: > > > > class document: > > def __init__(self, pages=[]): > > self.pages = pages[:] > > > > > > class document: > > def __init__(self, pages=None): > > if pages is None: > > self.pages = [] > > else: > > self.pages = pages > > I'm not sure. Personally I somehow favour the second option (which is > quite Pythonic btw), but I remember a "bug" Jörg came up with some > time ago. It was about an internal reordering of some attributes and > it was done on the original list passed to the method. I understand > that such a behaviour can be very troublesome and shouldn't be done > for such an end-user library like PyX. > > So let me formulate a rule of thumb: Go for option 1 for all > attributes, which are not read-only. (For read-only attribute *no* > copy is necessary and should not be made.) Jörg, do you agree? Sounds very reasonable to me. > > I will scan through the code to eliminate all other occurrences of > > this problem. > > Thanks a lot! Thanks from me, as well. These kind of errors tend to be hard to spot. Jörg |
From: Alan G I. <ai...@am...> - 2007-08-01 13:39:10
|
On Wed, 1 Aug 2007, Andre Wobst apparently wrote: > For read-only attribute no copy is necessary and should > not be made. Perhaps use a tuple instead of a list for read only attributes? (Sadly tuples still lack some useful methods they should have: are these needed?) Sorry if this is just noise, Alan Isaac |
From: Andre W. <wo...@us...> - 2007-08-01 15:37:24
|
Hi Alan, On 01.08.07, Alan G Isaac wrote: > On Wed, 1 Aug 2007, Andre Wobst apparently wrote: > > For read-only attribute no copy is necessary and should > > not be made. > > Perhaps use a tuple instead of a list for read only > attributes? (Sadly tuples still lack some useful methods > they should have: are these needed?) -1 to that. Tuples are tuples and not lists. As I'm writing rules of thumb today, let me add a whole list here. - Tuples containing no elements should never occur. - Tuples containing only one element should never occur. - Tuples should usually contain different elements of different type, or at least different meaning. A point (x, y) is perfect. That's a tuple, not a list. X is one coordinate, y the other. Different meaning. - Tuples are basically a simple (and ugly, but speedy and memory-efficient) way of expressing: class point: def __init__(self, x, y): self.x = x self.y = y This means p = (x, y) should better be written as p = point(x, y) and p[0] and p[1] should become p.x and p.y. The bracket notation of tuples looks like tuples are similar to lists, but they aren't. To my mind they are just a quick and dirty way of expressing some code as shown in the point example above. - Tuples are useful as dictionary keys, and that's about it. (I know not all off the points are valid in all cases, but they are good coding rules to start with ... at least if you ask me. :-) ) Overall, don't use tuples. If you're a python beginner, never use tuples at all ... :-) Well, I'm a bit crude today, but ... this advice it not that bad. André -- by _ _ _ Dr. André Wobst / \ \ / ) wo...@us..., http://www.wobsta.de/ / _ \ \/\/ / PyX - High quality PostScript and PDF figures (_/ \_)_/\_/ with Python & TeX: visit http://pyx.sourceforge.net/ |
From: Joerg L. <jo...@us...> - 2007-08-01 15:53:45
|
Hi Alan, On 01.08.07, Andre Wobst wrote: > On 01.08.07, Alan G Isaac wrote: > > On Wed, 1 Aug 2007, Andre Wobst apparently wrote: > > > For read-only attribute no copy is necessary and should > > > not be made. > > > > Perhaps use a tuple instead of a list for read only > > attributes? (Sadly tuples still lack some useful methods > > they should have: are these needed?) If you need such methods, you almost certainly don't want to use tuples but a list. > -1 to that. Tuples are tuples and not lists. As I'm writing rules of > thumb today, let me add a whole list here. I fully agree with all of the points and just want to add for the more mathematically inclined that tuples are nothing more than cartesian products. Jörg |
From: Alan G I. <ai...@am...> - 2007-08-01 17:01:46
|
>> Sadly tuples still lack some useful methods they should >> have: are these needed?) On Wed, 1 Aug 2007, Joerg Lehmann apparently wrote: > If you need such methods, you almost certainly don't want to > use tuples but a list. I meant, does PyX ever use such methods when processing read only attributes? If not, then tuples could be used, thereby taking advantage of immutability. (A natural match to "read only".) Cheers, Alan Isaac |
From: Joerg L. <jo...@us...> - 2007-08-02 12:49:30
|
Hi Alan, On 01.08.07, Alan G Isaac wrote: > >> Sadly tuples still lack some useful methods they should > >> have: are these needed?) > > On Wed, 1 Aug 2007, Joerg Lehmann apparently wrote: > > If you need such methods, you almost certainly don't want to > > use tuples but a list. > > I meant, does PyX ever use such methods when processing read > only attributes? If not, then tuples could be used, > thereby taking advantage of immutability. (A natural > match to "read only".) This question is difficult to answer without knowing the methods you refer to. I can only guess that you were speaking about the index and count methods, which are the only list methods that do not modify the list. I meant that although being compatible with the immutability property they do not make much sense for tuples. Cheers, Jörg |
From: Alan G I. <ai...@am...> - 2007-08-02 13:01:44
|
On Thu, 2 Aug 2007, Joerg Lehmann apparently wrote: > I can only guess that you were speaking about the index > and count methods, which are the only list methods that do > not modify the list. Right. > I meant that although being compatible with the > immutability property they do not make much sense for > tuples. Well of course there have been other views on this. Guido's own comment on the absence was: "there isn't a real good reason." And my personal view is that these methods should be available for tuples, thereby encouraging the the good practice of using tuples when immutability is a relevant property. Anyway, this seems a bit OT for this list, so you can have the last word. (I.e., I'll shut up now.) Cheers, Alan |
From: Joerg L. <jo...@us...> - 2007-08-02 14:44:08
|
Hi Alan, On 02.08.07, Alan G Isaac wrote: > Well of course there have been other views on this. > Guido's own comment on the absence was: > "there isn't a real good reason." Interesting, this I didn't know. > And my personal view is that these methods should be > available for tuples, thereby encouraging the the good > practice of using tuples when immutability is a relevant > property. > > Anyway, this seems a bit OT for this list, so you can have > the last word. (I.e., I'll shut up now.) I take the last word and admit that there are different "schools" concerning the whole tuple-vs-list issue. In principle, one could argue that Python is missing an immutable list type ;-) But you're right: this is really off-topic... Cheers, Jörg |