Limits of Metaprogramming

castironpi castironpi at gmail.com
Mon Aug 4 13:49:45 EDT 2008


On Aug 4, 4:48 am, Wilson <PaulAlexWil... at gmail.com> wrote:
> Hi all,
>
> My problem is that I don't know if it's possible to edit these states
> and then write them back to .py. Firstly, if my editing tool was to
> create a new state, I would want to create the class (using type) and
> attach it to the imported state module somehow. I can't find
>
> Thanks,
> Paul

Yes it's possible, using type, but you can't attach it to the module
in any persistent way.  The next time you load the module, it's back
to the way it was.

I think this may be the hang-up in your design: if you think about
generating lines of code directly from the user's actions, you might
stay on the right track.  At that point, you can place them in the .py
file.  Then you can reimport it, or just execute the new lines
directly.

If this is your class,

class Auto54701:
  def next( self, input ):
     if( something ):
       return value1
     return value2

Here's how to work with it at the interactive prompt:

>>> s= """class Auto54701:
...   def next( self, input ):
...      if( something ):
...        return value1
...      return value2
... """
>>> s
'class Auto54701:\n  def next( self, input ):\n     if( something ):
\n       ret
urn value1\n     return value2\n'
>>> exec( s )
>>> Auto54701
<class __main__.Auto54701 at 0x00A80C60>
>>>

And by the way, you can't use pickle to store types.  There needs to
be some fleshed-out code to back them up.

Two more alternatives, which I can discuss more later, one where you
implement code as data, but it ends up being a lot like Python
anyway.  It only works if your classes' methods are going to be
simple, probably sequential if-s and assignments at most.

class Auto54701:
  def next( self, input ):
     if( something1 ):
       return value1
     elif( something2 ):
       return value2
     elif( something3 ):
       return value3
     elif( something4 ):
       return value4
    return value5

can be stored in data as

  [ ( something1, value1 ), ( something2, value2 ), ... ]

, and just checked in a loop, that you only have in code once, rather
than many times.

class GenericAuto:
  def next( self, input ):
    for something, value in conditionpairs:
      if( something ):
        return value
    return valuen

Two, if all your methods will have uniform signatures and closures,
you can store class methods as only their co_code objects:

>>> C.g.im_func.func_code.co_code
'd\x00\x00S'

And fabricate them dynamically into full live types as needed.



More information about the Python-list mailing list