#ifdef like question.

holger krekel pyth at devel.trillke.net
Tue May 14 10:24:06 EDT 2002


Roman Yakovenko wrote:
> Thanks for the help. I don't like the first version( I knew that I could implement it this way).
> The reason is simple if for each class \ function I will have 3 files than I'd rather will not use
> futures. So I'd like to see the second way. Even if it will be some dirty method. 
> I'll pay attention to comments.

i understand and share your oppinion. ok, then. 
let's make it as cleanly as possible. You basically do:

exec if_generators("""

    # generator version
    def func():
        yield 1
        yield 2

""", """

    # non-generator version
    def func():
        return [1,2]

""")

where if_generators is defined like this:

def if_generators(newway,oldway):
    import sys
    version=(int(sys.version[0]),int(sys.version[2]))
    if version >= (2,2):
        execstring = 'from __future__ import generators\nif 1:\n'+newway
    else:
        execstring = 'if 1:\n'+oldway
    return execstring

this works from python-version 1.5 onwards. 

Some points:

- You can use the exec-statement inside class definitions for 
  methods as well.  the 'if 1:' is there to allow nicer 
  identation. Otherwiese statements would have to start
  at column 0.

- execing a string constructs a new parsing-tree. 
  The restriction for 'from __future__ ...' is that
  it must appear at the top of parsing tree, not at
  the beginning of a module-file. 

- usually an imported module is byte-compiled in its place.
  in the above case the exec-string will *always* be parsed
  and compiled once at run-time.  this hurts if you have short-lived 
  scripts that import your module.

- when using multiple version of python with the same
  script in the same location, bytecompiling will quickly
  loose its purpose. This problem is not specific
  to the given example but applies to any such script, though.

- some people rightfully argue that doing 'exec str' 
  should be avoided in favor of 'exec str in g,l' or
  getting rid of it alltogether. But I don't see other sane ways 
  of achieving our goal. Maybe the person in question is reading
  this and comments :-)

have fun,

    holger





More information about the Python-list mailing list