473,322 Members | 1,496 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,322 software developers and data experts.

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

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()

but am recoiling a bit at the unnecessary conditional in there that I
think will be run on every execution - unless the compiler has some
magic detection of things like sys.version to compile out the
conditional as if it were a preprocessor directive (seems highly
unlikely!)?.

What is the pythonic thing to do? This is in a generally usable file,
not a package, so I don't want to make a version for each (which seems
to be what every package out there does). It seems to be begging for a
pre-processor directive set.

Thanks,
Russ

Mar 28 '06 #1
9 1323
Russell Warren wrote:
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.
the collections module was added in 2.4, so it's not clear what code you're
really using under 2.3. but since it's not a standard module, maybe you could
add the missing method yourself ?
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()

but am recoiling a bit at the unnecessary conditional in there that I
think will be run on every execution - unless the compiler has some
magic detection of things like sys.version to compile out the
conditional as if it were a preprocessor directive (seems highly
unlikely!)?.

What is the pythonic thing to do?


fork the function/method:

if sys.version_info < (2, 4):
def myfunc(self):
# using deque emulation
return self.myDeque.pop(0)
else:
def myfunc(self):
return self.myDeque.popleft()

or wrap the non-standard deque class in a compatibility wrapper:

if sys.version_info < (2, 4):
class mydequeclass(deque):
def popleft(self):
return self.pop(0)

...

return self.myDeque.popleft()

</F>

Mar 28 '06 #2
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

Mar 28 '06 #3
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.
collections is new in 2.4 -- I assume you mean list.pop(0) versus
collections.deque.popleft().
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()

but am recoiling a bit at the unnecessary conditional in there that I
think will be run on every execution - unless the compiler has some
magic detection of things like sys.version to compile out the
conditional as if it were a preprocessor directive (seems highly
unlikely!)?.

What is the pythonic thing to do? This is in a generally usable file,
not a package, so I don't want to make a version for each (which seems
to be what every package out there does). It seems to be begging for a
pre-processor directive set.


Here's how I would rewrite your example:

try:
from collections import deque
except ImportError:
class deque(list):
def popleft(self):
return self.pop(0)

# in your method:
return self.myDeque.popleft()

That way the performance impact almost vanishes for the newer python and
your code is less cluttered with if ... else statements that are only there
to pick the version specific code.

Peter
Mar 28 '06 #4
> the collections module was added in 2.4

Ah... sorry about that. I should have checked my example more closely.
What I'm actually doing is rebinding some Queue.Queue behaviour in a
"safe" location like this:

def _get(self):
ret = self.queue.popleft()
DoSomethingSimple()
return ret

And self.queue.popleft() used to be self.queue.pop(0). self.queue is a
deque object in 2.4 so I just used transferred that unluckily to the
post in a poor attempt to simplify it - I had no clue that it was new.
Should have made one up from scratch.

Anyway - it worked... you've answered my question perfectly, thanks. I
hadn't considered that the module loading phase could basically used
for preprocessing. You even helped by subtly providing a better
version checker... I didn't even know you could use < with a tuple like
that. I'll have to look into the logic rules there.

Russ

Mar 28 '06 #5
Thanks guys - all great responses that answered my question in a few
different ways with the addition of some other useful tidbits!

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


Gotta love the response time of this newsgroup...

Russ

Mar 28 '06 #6

Russell Warren wrote:
the collections module was added in 2.4


Ah... sorry about that. I should have checked my example more closely.
What I'm actually doing is rebinding some Queue.Queue behaviour in a
"safe" location like this:

def _get(self):
ret = self.queue.popleft()
DoSomethingSimple()
return ret


What you should have done is call the base class's _get method, like
this:

def _get(self):
ret = Queue._get(self)
DoSomethingSimple()
return ret

This'll work in 2.3, 2.4, and if they were to change the type of the
queue again in 2.5, it would still work without any changes. Don't
redo the work the base class does if you don't have to.
Carl Banks

Mar 29 '06 #7
In article <11**********************@v46g2000cwv.googlegroups .com>,
Russell Warren <ru************@gmail.com> wrote:
Mar 29 '06 #8
Yes, I definitely should have done that for that case. I'm not
entirely sure why I didn't. If I had, though, I may not have been
prompted to ask the question and get all the other great little
tidbits!

Mar 30 '06 #9
Well, Bill Mill and I simultaneously and independently decided to write
a preprocessor to strip out the unfortunate "@" decorator syntax. I
think we were both aiming at a polemic purpose rather than a practical
one, but as time fades it seems less clear what we were simultaneously
inspired to achieve. Each of us did a crude pass at it and then on
encountering each other's approach realized a truly satisfactory
implementation would probably be harder than it was worth...

In any case isn't ipython an instance of a useful preprocessor?

mt

Mar 30 '06 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: GriffithsJ | last post by:
Hi I have been given some text that needs to be displayed on a web page. The text is pre-formatted (includes things like lists etc) and displays okay if I wrap it using the <pre/> tag. ...
2
by: Porthos | last post by:
Hi All, I'm building an XSL document that puts two types of information in a table dimension: preformatted data and data extracted from my XML document (see below) <table> <tr>
7
by: Alan Illeman | last post by:
How do I set several different properties for PRE in a CSS stylesheet, rather than resorting to this: <BODY> <PRE STYLE="font-family:monospace; font-size:0.95em; width:40%; border:red 2px...
8
by: Jarno Suni not | last post by:
It seems to be invalid in HTML 4.01, but valid in XHTML 1.0. Why is there the difference? Can that pose a problem when such a XHTML document is served as text/html?
8
by: Jim Butler | last post by:
What are the drawbacks if any to this approach of not using the gac for shared components... basically having a central directory located outside of iis, that all web applications have a virtual...
7
by: Rocky Moore | last post by:
I have a web site called HintsAndTips.com. On this site people post tips using a very simply webform with a multi line TextBox for inputing the tip text. This text is encode to HTML so that no...
9
by: Eric Lindsay | last post by:
I can't figure how to best display little snippets of shell script using <pre>. I just got around to organising to bulk validate some of my web pages, and one of the problems occurs with Bash...
23
by: Xah Lee | last post by:
The Concepts and Confusions of Pre-fix, In-fix, Post-fix and Fully Functional Notations Xah Lee, 2006-03-15 Let me summarize: The LISP notation, is a functional notation, and is not a...
14
by: Schraalhans Keukenmeester | last post by:
I am building a default sheet for my linux-related pages. Since many linux users still rely on/prefer viewing textmode and unstyled content I try to stick to the correct html tags to pertain good...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.