From mark at microenh.com Mon Apr 14 16:23:03 2008 From: mark at microenh.com (Mark Erbaugh) Date: Mon, 14 Apr 2008 10:23:03 -0400 Subject: [CentralOH] __slots__ Message-ID: <1208182983.10539.12.camel@P1900> I am implementing a class to handle data retrieved from a PostgreSQL database using psycopg2. >From the Python Language Reference Manual: "By default, instances of both old and new-style classes have a dictionary for attribute storage. This wastes space for objects having very few instance variables. The space consumption can become acute when creating large numbers of instances." In my application, there is an instance for each row returned from a SQL query, so it seems that __slots__ might be helpful. However, to use the instance to update the data on the server, you need a dict as the parameter passing is done with dictionary syntax: cursor.execute('update table set field=%(f1)s', {'f1':f1val}) If the class doesn't use __slots__, you can just use the instance's __dict__ data member. I could add a method to the class to return a suitable dict, but would that be less overhead than skipping __slots__ altogether? There will be more times that data is retrieved than updated, so this method won't be called on each instance created. Or is there a better way? Thanks, Mark From mark at microenh.com Tue Apr 15 15:06:31 2008 From: mark at microenh.com (Mark Erbaugh) Date: Tue, 15 Apr 2008 09:06:31 -0400 Subject: [CentralOH] My First metaclass Message-ID: <1208264792.8353.24.camel@P1900> I've been reading Wesley Chun's "Core Python Programming 2nd Edition" and working on a large Python / wxPython / Postgres (psygopg2) database application. I wanted to simplify handling of the data retrieved from the database, which may also be updated and written back to the database. psygopg2 is DBAPI 2 compliant which means and data from a query is returned as a list (rows) of tuples (columns). psycopg2 uses the 'pyformat' style for parameter passing which expects a mapping to provide parameters. I wanted to make it easier to use the data from a query. I wanted to track if the user had updated a row, and which columns in that row had been updated. I needed to allow the data to track new rows that had been inserted and rows that needed to be deleted. Lastly, I wanted the data structure to be able to handle related "child" data, such as lineitems on an invoice or purchase order. I developed a system of classes that met these needs. However, it was was a little cumbersome to use and I found myself putting off adding new database functionality as getting everything working was tedious. I looked at some of the Python recipes such as SuperTuple and DBTuple, but these didn't quite meet my needs. Then I read more about classes in Chun's book, especially the __slots__ parameter, descriptors and metaclasses. I felt that that these might be the key. After a day of playing with things, I have a working class that meets my requirements. While the ancestor class uses some of these advanced (to me) features, descendant classes are extremely simple, all one needs to do is define the __slots__ attribute. It meets my current needs: 1) struct-like (x.colname) named column access. Note that slots are used so a misspelled column name will trigger an exception 2) mapped access (x['colname']) 3) automatic tracking of update, insert and delete as well as tracking which columns have been updated 4) inclusion of additional columns to handle related data. For a parent child relationship, this field could be a list containing instances of another descendant class. Here's what I came up with. Feel free to use it if appropriate, but since this is my first foray into metaclasses, I would appreciate any comments/criticisms. Mark Erbaugh ============================================== class D(object): """ descriptor class When a data member is updated, this descriptor will automatically set the class's _updated member to True (indicating that the row has been updated) and add the column name to the _c_updated set (indicating that the individual column has been updated). """ __slots__ = ('index','name') def __init__(self, index, name): self.index = index self.name = name def __get__(self, obj, typ=None): return obj._data[self.index] def __set__(self, obj, value): try: x = obj._data[self.index] <> value except: x = True if x: obj._updated = True obj._c_updated.add(self.name) obj._data[self.index] = value # --------------------------------------- class BaseMeta(type): def __new__(cls, name, bases, dict): if name <> 'Base': for i,n in enumerate(dict['__slots__']): dict[n] = D(i,n) del i,n return type.__new__(cls, name, bases, dict) class Base(object): """ base class for 'record-like' objects designed to hold SQL query data field names are the names passed in in the descendents __slots__ attribute fields can be accessed by name x.name, or as a mapping x['name'] (mapping designed for dict-type parameters) fields _deleted and _inserted can be used to track deletes and inserts fields _updated (any field updated) automatically maintained method c_updated(col ) returns True if column has been updated minimum for derived class: define field names (and order) in class __slots__ attribute example usage: class AddressType(Base): __slots__ = ('ctid','rsn','postal','name') # end of class cursor.execute('select ctid,rsn,postal,name from at') return [AddressType(i) for i in cursor.fetchall()] note: can define more fields than used in query """ __metaclass__ = BaseMeta __slots__ = ('_updated', '_deleted', '_inserted', '_c_updated', '_data') def __init__(self, data, inserted=False): """ data is a sequence of field values in the same order as the descendent classes __slots__ attribute. instance's _inserted flag will be set to inserted The sequence may be shorter than the __slots__ attribute in which case trailing values will be None. """ self._data = [None] * len(self.__slots__) self._data[:len(data)] = data self._updated = False self._c_updated = set() self._deleted = False self._inserted = inserted def reset_update(self): self._updated = False self._c_updated.clear() def __getitem__(self, x): return self.__getattribute__(x) def __setitem__(self, i, x): self.__setattr__(i, x) def c_updated(self, x): return x in self._c_updated # --------------------------------------- if __name__ == '__main__': import application.utility.db_access.se_access as DB class Child(Base): """ descendent class example: minimum requirement, define field names and order in __slots__ attribute """ __slots__ = ('ctid','rsn','postal','name') DB.logon('development','dev') c= DB.CONN.cursor() c.execute("select ctid,rsn,postal,name from at") r = [Child(i) for i in c.fetchall()] From samus at codeargyle.com Tue Apr 15 14:56:21 2008 From: samus at codeargyle.com (Sam Corder) Date: Tue, 15 Apr 2008 08:56:21 -0400 (EDT) Subject: [CentralOH] My First metaclass In-Reply-To: <1208264792.8353.24.camel@P1900> Message-ID: <12703083.2031208264181582.JavaMail.root@spring.codeargyle.com> Out of curiosity did you ever look at any of the ORM libraries out there? Django's ORM can be used outside of the framework and it is half decent. SQLAlchemy is also reputed to be very nice though I have not used it. I'd hate to see you reinvent the wheel without know that it exists and what you are doing seems to be evolving towards it. Don't get me wrong. I'm not knocking your learning experience. I love it when I get a chance to dig deep into something like that but I usually have a deadline and if I don't have to bother reinventing wheels I'll take that route. -Sam ----- Original Message ----- From: Mark Erbaugh To: CentralOH at python.org Sent: Tuesday, April 15, 2008 9:06:31 AM GMT-0500 Auto-Detected Subject: [CentralOH] My First metaclass I've been reading Wesley Chun's "Core Python Programming 2nd Edition" and working on a large Python / wxPython / Postgres (psygopg2) database application. I wanted to simplify handling of the data retrieved from the database, which may also be updated and written back to the database. psygopg2 is DBAPI 2 compliant which means and data from a query is returned as a list (rows) of tuples (columns). psycopg2 uses the 'pyformat' style for parameter passing which expects a mapping to provide parameters. I wanted to make it easier to use the data from a query. I wanted to track if the user had updated a row, and which columns in that row had been updated. I needed to allow the data to track new rows that had been inserted and rows that needed to be deleted. Lastly, I wanted the data structure to be able to handle related "child" data, such as lineitems on an invoice or purchase order. I developed a system of classes that met these needs. However, it was was a little cumbersome to use and I found myself putting off adding new database functionality as getting everything working was tedious. I looked at some of the Python recipes such as SuperTuple and DBTuple, but these didn't quite meet my needs. Then I read more about classes in Chun's book, especially the __slots__ parameter, descriptors and metaclasses. I felt that that these might be the key. After a day of playing with things, I have a working class that meets my requirements. While the ancestor class uses some of these advanced (to me) features, descendant classes are extremely simple, all one needs to do is define the __slots__ attribute. It meets my current needs: 1) struct-like (x.colname) named column access. Note that slots are used so a misspelled column name will trigger an exception 2) mapped access (x['colname']) 3) automatic tracking of update, insert and delete as well as tracking which columns have been updated 4) inclusion of additional columns to handle related data. For a parent child relationship, this field could be a list containing instances of another descendant class. Here's what I came up with. Feel free to use it if appropriate, but since this is my first foray into metaclasses, I would appreciate any comments/criticisms. Mark Erbaugh From mark at microenh.com Tue Apr 15 16:07:51 2008 From: mark at microenh.com (Mark Erbaugh) Date: Tue, 15 Apr 2008 10:07:51 -0400 Subject: [CentralOH] My First metaclass In-Reply-To: <12703083.2031208264181582.JavaMail.root@spring.codeargyle.com> References: <12703083.2031208264181582.JavaMail.root@spring.codeargyle.com> Message-ID: <1208268471.11686.12.camel@P1900> On Tue, 2008-04-15 at 08:56 -0400, Sam Corder wrote: > Out of curiosity did you ever look at any of the ORM libraries out > there? Django's ORM can be used outside of the framework and it is > half decent. SQLAlchemy is also reputed to be very nice though I have > not used it. I'd hate to see you reinvent the wheel without know that > it exists and what you are doing seems to be evolving towards it. > Don't get me wrong. I'm not knocking your learning experience. I > love it when I get a chance to dig deep into something like that but I > usually have a deadline and if I don't have to bother reinventing > wheels I'll take that route. Sam, I played with Django and SQLAlchemy over a year ago, but don't remember much. You raise an interesting point. I wonder how one decides whether it's better to build your own or borrow someone else's. There certainly is a lot of good stuff out there to be used. Even though the open source stuff may be free to use, there is still time involved in learning how to use it and how to incorporate it into your application. Also, if you build your own open source application on other's routines, you have to keep up with changes to those routines to make sure that updates don't break your code. OTOH, you do get the advantage of code that has had more time put into it. I sort of faced this same issue on a larger scale when I started this project. There were several open source packages already released that do things similar to what I am trying to do. Unfortunately, none that I found were directly usable out of the box or even with minimal customization. I had to decide whether it would be easier to spend the time learning how to customize them or to start from scratch. Fortunately for me, a client had also reviewed several of these packages and didn't like the overall operation and is willing to partially support my development effort. Mark From bmintern at gmail.com Tue Apr 15 21:51:05 2008 From: bmintern at gmail.com (Brandon Mintern) Date: Tue, 15 Apr 2008 15:51:05 -0400 Subject: [CentralOH] My First metaclass In-Reply-To: <1208264792.8353.24.camel@P1900> References: <1208264792.8353.24.camel@P1900> Message-ID: <4c0fccce0804151251p43fab897g5d2ace0610212f89@mail.gmail.com> I've spent a while now trying to wrap my head around your code, and I'm finally starting to see what's going on. I have a nagging feeling that a similarly-elegant solution could be had without resorting to a 3-tier metaclass structure. That aside, I do have some comments on the code you have provided. The first thing that stuck out to me was the pervasive use of "<>". I have never seen this used in any recently-written Python code, and according to section 3.3 of the Python 2.5.1 docs, "!= is the preferred spelling; <> is obsolescent." I say that not because it adversely affects your code in this instance, but because I assume that you do this in all your code, and it's generally considered bad style. In fact, Guido removed it from Python 3000 back in 2006. Another couple of lines that took me a second to figure out what was going on was self._data = [None] * len(self.__slots__) self._data[:len(data)] = data I generally try to avoid using the []*n construct because when used on mutable types, it can really byte you. Consider: > a = [[]]*3 > a[0].append(0) > a -> [[0], [0], [0]] Additionally, the two lines just weren't all that clear to me what they were doing. Using islice, chain, and repeat from itertools, I would personally do something like: self._data = list(islice(chain(data, repeat(None)), len(self.__slots__))) I think that would be an improvement because it makes it clear exactly what _data is: a list of len(self.__slots__) elements composed of the elements of data followed by repeated Nones. It has the additional benefit of not first building a list of Nones, only to replace them with different items on the next line. I'm sorry to not have more comments on your actual metaclass structure, but I fear I've already spent too much time on this reply. Brandon On Tue, Apr 15, 2008 at 9:06 AM, Mark Erbaugh wrote: > I've been reading Wesley Chun's "Core Python Programming 2nd Edition" > and working on a large Python / wxPython / Postgres (psygopg2) database > application. I wanted to simplify handling of the data retrieved from > the database, which may also be updated and written back to the > database. psygopg2 is DBAPI 2 compliant which means and data from a > query is returned as a list (rows) of tuples (columns). psycopg2 uses > the 'pyformat' style for parameter passing which expects a mapping to > provide parameters. > > I wanted to make it easier to use the data from a query. I wanted to > track if the user had updated a row, and which columns in that row had > been updated. I needed to allow the data to track new rows that had been > inserted and rows that needed to be deleted. > > Lastly, I wanted the data structure to be able to handle related "child" > data, such as lineitems on an invoice or purchase order. > > I developed a system of classes that met these needs. However, it was > was a little cumbersome to use and I found myself putting off adding new > database functionality as getting everything working was tedious. > > I looked at some of the Python recipes such as SuperTuple and DBTuple, > but these didn't quite meet my needs. > > Then I read more about classes in Chun's book, especially the __slots__ > parameter, descriptors and metaclasses. I felt that that these might be > the key. After a day of playing with things, I have a working class > that meets my requirements. While the ancestor class uses some of these > advanced (to me) features, descendant classes are extremely simple, all > one needs to do is define the __slots__ attribute. It meets my current > needs: > > 1) struct-like (x.colname) named column access. Note that slots are used > so a misspelled column name will trigger an exception > > 2) mapped access (x['colname']) > > 3) automatic tracking of update, insert and delete as well as tracking > which columns have been updated > > 4) inclusion of additional columns to handle related data. For a parent > child relationship, this field could be a list containing instances of > another descendant class. > > Here's what I came up with. Feel free to use it if appropriate, but > since this is my first foray into metaclasses, I would appreciate any > comments/criticisms. > > Mark Erbaugh [code snipped] From wam at cisco.com Tue Apr 15 22:40:17 2008 From: wam at cisco.com (William McVey) Date: Tue, 15 Apr 2008 16:40:17 -0400 Subject: [CentralOH] My First metaclass In-Reply-To: <1208268471.11686.12.camel@P1900> References: <12703083.2031208264181582.JavaMail.root@spring.codeargyle.com> <1208268471.11686.12.camel@P1900> Message-ID: <1208292017.6141.81.camel@tardis> On Tue, 2008-04-15 at 10:07 -0400, Mark Erbaugh wrote: > You raise an interesting point. I wonder how one decides whether it's > better to build your own or borrow someone else's. I almost always prefer using functionality that meets my needs if it already exists and if it's compatible with my project. This compatibility evaluation has to happen both from a code quality standpoint as well as licensing standpoint. Unless there is some other external factor involved (e.g. I want to learn a new technology by implementing my own version of something), my first step is always a search to find what software already fits the niche I'm trying to fill. Even if something doesn't have all the features I'm looking for, I'll generally embrace, extend, and contribute back than roll my own, if I can help it. This is simply due to time. I have too many projects that I really care about than to rewrite components that already exist. Any time I spend writing my own version of something that has already been done and is of sufficient capability, is a distraction from writing the actual application I'm working on. > There certainly is a > lot of good stuff out there to be used. Even though the open source > stuff may be free to use, there is still time involved in learning how > to use it and how to incorporate it into your application. Sure, you have to learn to use the external components, but I've found that generally learning how to use a new tool/component/module is a lot faster than writing, debugging, documenting, and supporting your own version of the tool. Additionally, the time you spend in learning a new tool that actually has a community behind it (e.g. SQLAlchemy) is time that may have an a return on investment in the future as you encounter a new tool using that same library. > Also, if you > build your own open source application on other's routines, you have > to keep up with changes to those routines to make sure that updates > don't break your code. OTOH, you do get the advantage of code that > has had more time put into it. Well, keeping up with upstream changes is purely optional. You could just as well copy the particular pieces of code directly into your own codebase and be assured that future changes won't break your application. Enhancements and bug fixes could occur at your leisure, if at all. Of course, you will in general be doing yourself a favor if you keep your development tracking the upstream releases of your dependencies. -- William From mark at microenh.com Wed Apr 23 15:24:18 2008 From: mark at microenh.com (Mark Erbaugh) Date: Wed, 23 Apr 2008 09:24:18 -0400 Subject: [CentralOH] Eclipse Message-ID: <1208957058.11316.7.camel@P1900> I've started using Eclipse (v 3.3.0) with Pydev (v 1.3.8) and Subclipse (v 1.2.4) as a development platform under Ubuntu Dapper (6.06) and it's working well. I have seen one minor glitch: When using either the Navigator or Pydev Package Explorer display, after using working in Eclipse for a while, the little markings on the individual resource icons that indicate the version control status seem to get confused. In many cases the markings disappear. However, there is a little icon in the bottom of the window that shows the currently selected resource and it has the correct version control marking. Version control still seems to be working properly. The only way I have found to restore these markings is to exit Eclipse and restart it. Mark From david.car7 at gmail.com Thu Apr 24 02:54:03 2008 From: david.car7 at gmail.com (David Car) Date: Wed, 23 Apr 2008 20:54:03 -0400 Subject: [CentralOH] Eclipse In-Reply-To: <1208957058.11316.7.camel@P1900> References: <1208957058.11316.7.camel@P1900> Message-ID: <37f7fbce0804231754w3c9c5995jf5c762189dc5a13f@mail.gmail.com> I've been playing around with Eclipse as well using Pydev but I'm using Subversive as the SVN handler. Have you tried that plug-in at all? Seems to work pretty well, but I'm a diehard Emacs user, so not sure if I'll switch to Eclipse permanently. My 2 cents.... -David On 4/23/08, Mark Erbaugh wrote: > > I've started using Eclipse (v 3.3.0) with Pydev (v 1.3.8) and Subclipse > (v 1.2.4) as a development platform under Ubuntu Dapper (6.06) and it's > working well. I have seen one minor glitch: > > When using either the Navigator or Pydev Package Explorer display, after > using working in Eclipse for a while, the little markings on the > individual resource icons that indicate the version control status seem > to get confused. In many cases the markings disappear. However, there > is a little icon in the bottom of the window that shows the currently > selected resource and it has the correct version control marking. > > Version control still seems to be working properly. > > The only way I have found to restore these markings is to exit Eclipse > and restart it. > > Mark > > _______________________________________________ > CentralOH mailing list > CentralOH at python.org > http://mail.python.org/mailman/listinfo/centraloh > -- Regards, David -------------- next part -------------- An HTML attachment was scrubbed... URL: From mark at microenh.com Thu Apr 24 18:47:27 2008 From: mark at microenh.com (Mark Erbaugh) Date: Thu, 24 Apr 2008 12:47:27 -0400 Subject: [CentralOH] Eclipse In-Reply-To: <37f7fbce0804231754w3c9c5995jf5c762189dc5a13f@mail.gmail.com> References: <1208957058.11316.7.camel@P1900> <37f7fbce0804231754w3c9c5995jf5c762189dc5a13f@mail.gmail.com> Message-ID: <1209055647.5362.18.camel@P1900> On Wed, 2008-04-23 at 20:54 -0400, David Car wrote: > I've been playing around with Eclipse as well using Pydev but I'm > using Subversive as the SVN handler. Have you tried that plug-in at > all? Seems to work pretty well, but I'm a diehard Emacs user, so not > sure if I'll switch to Eclipse permanently. My 2 cents.... David, Thanks for the pointer. I hadn't hear of Subversive. I checked out their website, but couldn't find a way to download the add-on other as a local repository. I use a satellite connection for internet and the last time I tried to use a remote repository to install an add-on to Eclipse it didn't work, my CPU usage went to 100% and nothing happened (at least for a long time before I gave up). I downloaded that file and installed it as a local repository and it was just fine. I didn't research it, but I'm blaming the latency of the satellite connection. So far, there are two things from Idle that I miss in Eclipse: 1) an interactive shell window 2) a block indent / un-indent feature Mark From david.car7 at gmail.com Fri Apr 25 04:18:12 2008 From: david.car7 at gmail.com (David Car) Date: Thu, 24 Apr 2008 22:18:12 -0400 Subject: [CentralOH] Eclipse In-Reply-To: <1209055647.5362.18.camel@P1900> References: <1208957058.11316.7.camel@P1900> <37f7fbce0804231754w3c9c5995jf5c762189dc5a13f@mail.gmail.com> <1209055647.5362.18.camel@P1900> Message-ID: <37f7fbce0804241918s7f8bfc0bi4282f995f78f1e8c@mail.gmail.com> Mark, This is where I got the subversive plug-in: http://www.eclipse.org/subversive/downloads.php I used the Help->Software Updates->Find and Install and adde it. Subversive is in the incubation phase, so its on its way to becoming part of the standard Eclipsed distribution. Chances are it's here to stay. For the block indent (I use Idle every so often) I'm assuming you mean automatic block indent when hitting tab. In Eclipse, you want to use the Python editor from PyDev: Window->Preferences->General->Editors->File Associations Pick the *.py and *.pyw and in the Associated Editors window pick Add. Select the Python editor and make it the default. Next: Window->Preferences->PyDev->Typing Select what you would like. You should have automatic block indent. Hope this helps. -David On 4/24/08, Mark Erbaugh wrote: > > On Wed, 2008-04-23 at 20:54 -0400, David Car wrote: > > I've been playing around with Eclipse as well using Pydev but I'm > > using Subversive as the SVN handler. Have you tried that plug-in at > > all? Seems to work pretty well, but I'm a diehard Emacs user, so not > > sure if I'll switch to Eclipse permanently. My 2 cents.... > > > David, > > Thanks for the pointer. I hadn't hear of Subversive. I checked out their > website, but couldn't find a way to download the add-on other as a local > repository. I use a satellite connection for internet and the last time > I tried to use a remote repository to install an add-on to Eclipse it > didn't work, my CPU usage went to 100% and nothing happened (at least > for a long time before I gave up). I downloaded that file and installed > it as a local repository and it was just fine. I didn't research it, > but I'm blaming the latency of the satellite connection. > > So far, there are two things from Idle that I miss in Eclipse: > > 1) an interactive shell window > > 2) a block indent / un-indent feature > > > Mark > > -- Regards, David -------------- next part -------------- An HTML attachment was scrubbed... URL: From wam at cisco.com Fri Apr 25 17:40:40 2008 From: wam at cisco.com (William McVey) Date: Fri, 25 Apr 2008 11:40:40 -0400 Subject: [CentralOH] IDE's in general (was Re: Eclipse) In-Reply-To: <1209055647.5362.18.camel@P1900> References: <1208957058.11316.7.camel@P1900> <37f7fbce0804231754w3c9c5995jf5c762189dc5a13f@mail.gmail.com> <1209055647.5362.18.camel@P1900> Message-ID: <1209138040.6096.24.camel@tardis> Just as an FYI, I am a long time (10+ year) vi user. I used to jokingly state that my IDE of choice was a tabbed terminal window (I like mrxvt) and decent shell on a Linux/Unix system. At the most recent PyCon, Wingware gave away free licenses to their WingIDE Pro to individuals who stayed afterward to sprint. I figured I'd take them up on their offer to see how the other side lives. I surprised myself in that I found that I liked their product. It helps in that they have a vi emulation mode that far exceeds the emulation of just about any other tool I've looked at (certainly better than Eclipse's VI emulation). Although not perfect emulation of vi/vim, they have been very responsive in handling my bugs/feature requests. I still prefer my interactive python prompt in a terminal window over their python-prompt tool (I have better commandline history and editing capabilities using rlcompleter2). But when it comes to editing a new project, I'm now looking to Wing rather than loading up vi. Among the features I like most about their editor include: * better code completion * visible indents/whitespace (yes, I know vi/vim can do this, but not as nice) * integrated template engine for handling boilerplate code I've not yet got into their interactive debugger and haven't used their revision control integration (they support svn, cvs, perforce and I'm doing the git thing) or other advanced functionality, but overall I'm fan. Anyway, with the discussion of Eclipse, I felt like sharing my positive experience with another product in the same space. -- William From ericlake at gmail.com Fri Apr 25 18:16:45 2008 From: ericlake at gmail.com (Eric Lake) Date: Fri, 25 Apr 2008 12:16:45 -0400 Subject: [CentralOH] IDE's in general (was Re: Eclipse) In-Reply-To: <1209138040.6096.24.camel@tardis> References: <1208957058.11316.7.camel@P1900> <37f7fbce0804231754w3c9c5995jf5c762189dc5a13f@mail.gmail.com> <1209055647.5362.18.camel@P1900> <1209138040.6096.24.camel@tardis> Message-ID: <15c903070804250916yd65fb1dlf7d2589594255b69@mail.gmail.com> I'm starting to play with Eclipse + Pydev myself. I like using vim for most things though. Komodo Edit is another good IDE to use. On Fri, Apr 25, 2008 at 11:40 AM, William McVey wrote: > Just as an FYI, I am a long time (10+ year) vi user. I used to jokingly > state that my IDE of choice was a tabbed terminal window (I like mrxvt) > and decent shell on a Linux/Unix system. At the most recent PyCon, > Wingware gave away free licenses to their WingIDE Pro to individuals who > stayed afterward to sprint. I figured I'd take them up on their offer to > see how the other side lives. I surprised myself in that I found that I > liked their product. It helps in that they have a vi emulation mode that > far exceeds the emulation of just about any other tool I've looked at > (certainly better than Eclipse's VI emulation). Although not perfect > emulation of vi/vim, they have been very responsive in handling my > bugs/feature requests. > > I still prefer my interactive python prompt in a terminal window over > their python-prompt tool (I have better commandline history and editing > capabilities using rlcompleter2). But when it comes to editing a new > project, I'm now looking to Wing rather than loading up vi. Among the > features I like most about their editor include: > * better code completion > * visible indents/whitespace (yes, I know vi/vim can do this, but > not as nice) > * integrated template engine for handling boilerplate code > > I've not yet got into their interactive debugger and haven't used their > revision control integration (they support svn, cvs, perforce and I'm > doing the git thing) or other advanced functionality, but overall I'm > fan. Anyway, with the discussion of Eclipse, I felt like sharing my > positive experience with another product in the same space. > > -- William > > > > _______________________________________________ > CentralOH mailing list > CentralOH at python.org > http://mail.python.org/mailman/listinfo/centraloh > -- Thanks, Eric Lake From steven_h at acm.org Fri Apr 25 21:39:48 2008 From: steven_h at acm.org (Steven Huwig) Date: Fri, 25 Apr 2008 15:39:48 -0400 Subject: [CentralOH] IDE's in general (was Re: Eclipse) In-Reply-To: <15c903070804250916yd65fb1dlf7d2589594255b69@mail.gmail.com> References: <1208957058.11316.7.camel@P1900> <37f7fbce0804231754w3c9c5995jf5c762189dc5a13f@mail.gmail.com> <1209055647.5362.18.camel@P1900> <1209138040.6096.24.camel@tardis> <15c903070804250916yd65fb1dlf7d2589594255b69@mail.gmail.com> Message-ID: <7505f2a60804251239x4caf1a64u940f7969fd23565c@mail.gmail.com> Emacs 22 introduced an improved Python mode out of the box. - It will look up Python documentation for the symbol under your cursor (both online through help() and offline through info-formatted Python library documentation). - The Emacs Code Browser will give you the class/variable/method/function tree, like PyDev's outline view. - It will complete symbols based on a running Python process - It does the usual Emacs interaction mode (load file, load class, load method, etc) with the running Python process. - Other stuff I can't remember offhand. This is a recent improvement -- for six years or so, one had to jump through hoops to get a nice Python mode working in Emacs. Unless one were already committed to using Emacs, it would hardly have been worth it. Personally I find myself jumping around too quickly between tasks, and using too many shell commands, to use Eclipse and similar systems effectively. The fact that the Emacs keystrokes are embedded in my brain doesn't help much. -- Steve From ericlake at gmail.com Fri Apr 25 21:56:49 2008 From: ericlake at gmail.com (Eric Lake) Date: Fri, 25 Apr 2008 15:56:49 -0400 Subject: [CentralOH] IDE's in general (was Re: Eclipse) In-Reply-To: <7505f2a60804251239x4caf1a64u940f7969fd23565c@mail.gmail.com> References: <1208957058.11316.7.camel@P1900> <37f7fbce0804231754w3c9c5995jf5c762189dc5a13f@mail.gmail.com> <1209055647.5362.18.camel@P1900> <1209138040.6096.24.camel@tardis> <15c903070804250916yd65fb1dlf7d2589594255b69@mail.gmail.com> <7505f2a60804251239x4caf1a64u940f7969fd23565c@mail.gmail.com> Message-ID: <15c903070804251256g7d0b12c6o468e2fdfd3bfb9f6@mail.gmail.com> I tried Emacs for a little bit just to try to learn it. Even though I am not an expert Vim user I am used to the key bindings that Vim uses now. Switching is hard to do. -- Thanks, Eric Lake