From: Francesc A. <fa...@py...> - 2004-09-16 16:48:14
|
Dear PyTables users, I'm pondering to disable most of __call__() methods is PyTables objects because of two things: 1.- ipython (http://ipython.scipy.org/), which is a very good shell for Python adds by default the parenthesis '()' if you type just a name at the prompt and nothing more. Example: In [7]: float ------> float() Out[7]: 0.0 This is considered a good thing for most uses. Unfortunately, PyTables is designed to make use of bare object names to print a description of the object. That is, in the standard python console: >>> f.root.small /small (Group) 'small Group' children := ['create_worst' (Table), 'search_best' (Group), 'search_worst' (Group), 'create_best' (Table)] but the same in ipython gives: In [9]: f.root.small ------> f.root.small() Out[9]: <generator object at 0x415d490c> which is not was the user intended usually. 2.- More importantly, in my struggle to make interactive work with pytables easy, I'm afraid that I've abused a bit of the __call__ method, in most cases being introduced as a shortcut basically. For example, this is a typical use: >>> names=[ x['name'] for x in table(start=2, stop=1000) if x['TDCcount']>3] which is the same as: >>> names=[ x['name'] for x in table.iterrows(start=2, stop=1000) if x['TDCcount']>3] As I see it now, I find the second version much more clear, and although it is a bit more expensive to type, if we follow the mantra "explicit is better than implicit" I definitely think that the second is the way to go. So, these are the reasons why I'm planning to remove most of the __call__() methods and, if necessary, replace them by acurate method names. Although I think this is a good thing (TM), this may pose problems of backward compatibility with existing programs, and this is why I'm asking here. What do you think? You would like the change? That might cause problems with your programs? Do you have a better alternative? Cheers, -- Francesc Alted |
From: <st...@st...> - 2004-09-16 17:14:22
|
Removing the __call__() methods would make me happier. In code I (should) always write the long version anyway, because it is easier to read. And interactively, the call methods save steps only at a normal python prompt, they are an inconvenience in ipython. -- Stan |
From: Ivan V. i B. <iv...@ca...> - 2004-09-27 10:29:56
|
On Thu, Sep 16, 2004 at 01:14:12PM -0400, st...@st... wrote: > Removing the __call__() methods would make me happier. > In code I (should) always write the long version anyway, > because it is easier to read. And interactively, the > call methods save steps only at a normal python prompt, > they are an inconvenience in ipython.=20 I absolutely agree with removing those methods, since they quite obscure the source. In fact I am writing this mail to discuss a new interface I have devised for navigation in PyTables. Of course it is not my intention for it to go into the next version, but I'd appreciate your opinion. I call this the =E2=80=9Cheaven and earth=E2=80=9D interface, but I r= ecognise the name is quite arbitrary. Given the following hierarcy: (root) at1-. / \ .-at1 at2--(g1) [t2]--at2 / \ [t1] [a1] This hierarchy has two parallel =E2=80=9Cnatures=E2=80=9D, one that c= an be accessed by string paths (such as '/g1/a1') using the getNode() method, and one that can be accessed by natural naming. Given a node in the hierarchy, one can =E2=80=9Cwarp=E2=80=9D from one nature to the other. = We will call the first nature the =E2=80=9Cheaven=E2=80=9C nature, and the second one = the =E2=80=9Cearth=E2=80=9D nature. In the heaven nature, node and attribute identifiers are never used as Python identifiers, but strings, which would allow them to have any form (as long as they have no slashes). As said, nodes are accessed via the getNode() method, so any other method name can be used with no risk of clashing. Attribute sets are accessed via a node's getAttributes() method (alternatives: an attributes() method or an =E2=80=9Cattrs=E2=80= =9D attribute). Attributes in an attribute set may be accessed using some method, which could easily be __getitem__() (i.e. attrs['attrname']). In the earth nature, node and attribute identifiers are used as Python identifiers, so their form is restricted. Method names and special node attributes *always* start with =E2=80=9C_=E2=80=9D. Since the earth nature is aimed to interactive usage, the set of methods supported by a node or attribute set might be quite reduced, maybe only covering read-only access methods. The reason for this is avoiding redundance between heaven and earth classes. However, if the whole functionality is desired in both class types, coding the heaven methods in terms of the earth ones would simply be a matter of warping, calling the earth method and possibly warping back the result. root =3D h5file.getNode('/') g1 =3D h5file.getNode('/g1') g1 =3D root.getNode('g1') # Non-leaf nodes have a getNode() method ... t1 =3D g1.getNode('t1') # ... but only relative paths are allowed. a1 =3D root.getNode('g1/a1') t2 =3D h5file.getNode('/t2') # Absolute paths are only allowed on File ob= jects. # What if '.', '..', and absolute paths were allowed (using weakrefs) # on any (not only non-leaf) object? # t1 =3D g1.getNode('/g1/t1') # t1 =3D g1.getNode('./t1') # a1 =3D t1.getNode('../a1') # Getting a node's attribute in heaven. g1_at1 =3D root.getNode('g1').getAttributes()['at1'] # g1_at1 =3D root.getNode('g1').attributes()['at1'] # g1_at1 =3D root.getNode('g1').attrs['at1'] # Warping to earth. e_root =3D root.warp() e_g1 =3D e_root.g1 e_a1 =3D e_g1.a1 # Getting a node's attribute in earth. e_g1_at1 =3D e_g1._attrs.at1 e_g1_at2 =3D e_g1._attrs._warp()['at2'] e_t2_at2 =3D e_root.t2._attrs.t2 # Warping back to heaven. t1 =3D e_g1._warp().getNode('t1') # Example of earth node methods. def _someMethodReturningANode(self, args): return self._warp().someMethodReturningANode(args).warp() def _someMethodNotReturningANode(self, args): return self._warp().someMethodNotReturningANode(args) What do you think of this proposal? Does it look more or less intuitive? Do you guess more or less immediate problems (apart of interface incompatibility, of course)? Regards, Ivan --=20 Ivan Vilata i Balaguer @ FIGHT AGAINST SOFTWARE PATENTS! @ http://www.selidor.net/ @ http://EuropeSwPatentFree.hispalinux.es/ @ |
From: Norm P. <nj...@nj...> - 2004-09-16 17:27:02
|
+1 for "explicit is better" (the suggested change is fine, and as a complete pytables newbie, I don't have any affected production code) Thanks for making just the tool I need right now to manage a lot of industrial real-time data. Nice work! ----- Original Message ----- From: "Francesc Alted" <fa...@py...> To: <pyt...@li...> Sent: Thursday, September 16, 2004 12:47 PM Subject: [Pytables-users] Special __call__ method in PyTables objects > Dear PyTables users, > > I'm pondering to disable most of __call__() methods is PyTables objects > because of two things: > > 1.- ipython (http://ipython.scipy.org/), which is a very good shell for > Python adds by default the parenthesis '()' if you type just a name at the > prompt and nothing more. Example: > > In [7]: float > ------> float() > Out[7]: 0.0 > > This is considered a good thing for most uses. Unfortunately, PyTables is > designed to make use of bare object names to print a description of the > object. That is, in the standard python console: > > >>> f.root.small > /small (Group) 'small Group' > children := ['create_worst' (Table), 'search_best' (Group), 'search_worst' (Group), 'create_best' (Table)] > > but the same in ipython gives: > > In [9]: f.root.small > ------> f.root.small() > Out[9]: <generator object at 0x415d490c> > > which is not was the user intended usually. > > 2.- More importantly, in my struggle to make interactive work with pytables > easy, I'm afraid that I've abused a bit of the __call__ method, in most > cases being introduced as a shortcut basically. For example, this is a > typical use: > > >>> names=[ x['name'] for x in table(start=2, stop=1000) if x['TDCcount']>3] > > which is the same as: > > >>> names=[ x['name'] for x in table.iterrows(start=2, stop=1000) if x['TDCcount']>3] > > As I see it now, I find the second version much more clear, and although it > is a bit more expensive to type, if we follow the mantra "explicit is better > than implicit" I definitely think that the second is the way to go. > > So, these are the reasons why I'm planning to remove most of the __call__() > methods and, if necessary, replace them by acurate method names. Although I > think this is a good thing (TM), this may pose problems of backward > compatibility with existing programs, and this is why I'm asking here. > > What do you think? You would like the change? That might cause problems with > your programs? Do you have a better alternative? > > Cheers, > > -- > Francesc Alted > > > > ------------------------------------------------------- > This SF.Net email is sponsored by: YOU BE THE JUDGE. Be one of 170 > Project Admins to receive an Apple iPod Mini FREE for your judgement on > who ports your project to Linux PPC the best. Sponsored by IBM. > Deadline: Sept. 24. Go here: http://sf.net/ppc_contest.php > _______________________________________________ > Pytables-users mailing list > Pyt...@li... > https://lists.sourceforge.net/lists/listinfo/pytables-users > |