Seems like I want a pre-processor, but...

Kent Johnson kent at kentsjohnson.com
Tue Mar 28 18:42:13 CEST 2006


Russell Warren wrote:
> After some digging it seems that python does not have any equivalent to
> C's #if directives, and I don't get it...
> 
> For example, I've got a bit of python 2.3 code that uses
> collections.deque.pop(0) in order to pop the leftmost item.  In python
> 2.4 this is no longer valid - there is no argument on pop (rightmost
> only now) and you call .popleft() instead.
> 
> I would like my code to work in both versions for now and simply want
> to add code like:
> 
> if sys.version[:3] == "2.3":
>   return self.myDeque.pop(0)
> else:
>   return self.myDeque.popleft()

Often you can make these tests one-time by defining an appropriate 
object whose value depends on the test, then using that object instead 
of repeatedly making the test. In this case, I assume the code above is 
inside a class method. You could have the class conditionally define a 
myPopLeft() method like this (not tested):

class MyClass(object):
   ...
   if sys.version[:3] == "2.3":
     def myPopLeft(self):
       return self.myDeque.pop(0)
   else:
     def myPopLeft(self):
       return self.myDeque.popleft()

Now the class has a myPopLeft() method that does the right thing, and 
sys.version is only tested once, at class declaration time.

You might want to make the condition explicitly on the deque class, 
also, using has_attr(deque, 'popleft').

Another example is the common code used to define 'set' portably across 
Python 2.3 and 2.4:

try:
   set
except NameError:
   from sets import Set as set


In general the idea is to move the test from 'every time I need to do 
something' to 'once when some name is defined'.

Kent




More information about the Python-list mailing list