[Q] python vs checker.py maxlocals

Andrew Dalke adalke at mindspring.com
Thu Mar 27 04:08:02 CET 2003

achrist at easystreet.com
> I've got a pre-defined datastructure that I'm building.  Something like
> this hypothetical example:
>     universe   = tree.AddRoot("The Universe")
>     milkyWay    = AddTreeItem( tree,  universe,    "Our Galaxy" )
>     solarSystem = AddTreeItem( tree,  milkyWay,    "Solar System" )
>     earth       = AddTreeItem( tree,  solarSystem, "Earth" )
>     kansasCity  = AddTreeItem( tree,  earth,       "Kansas City" )
>   ... and so on ad nauseum

BTW, I think there was a limit of 255 variables in a local function.  That's
since been fixed - I just made a function with 65537 variables.

> Is there any more pythonic idiom for this?

One is to make a wrapper for the explicit tree calls, using __getattr__
and __setattr__ methods (or __getattribute__ for newer Pythons?)
The result would look like

universe = TreeWrapper(tree, "The Universe", f0)
universe.milkyWay = ("Our Galaxy", f1)
universe.milkyWay.solarSystem = ("Solar System", f2)

The implementation looks something like

class TreeWrapper:
    def __init__(self, tree, text, f):
      self.tree = tree
      self.tree.AddRoot(text, f)
      self.names = {}
    def __getattr__(self, name):
      if name not in self.names:
        raise AttributeError(name)
      return NodeWrapper(self.tree)
    def __setattr__(self, name, (text, f))
      self.tree.AddTreeItem(self.tree, name, text, f)
      self.names[name] = 1

Another way is to define a mini-language, either as a new

  s = """\
"The Universe", f1
    "Our Galaxy", f2
        "Milky Way", f3
          "Solar System", f4
    "Andromeda", f5

with a parser to convert this into Python calls (it's a pretty
simple stack-based implementation) and some introspection to
turn function names into actual references.  You might consider
YAML as an existing mini-language which could be post-processed
to get the function references.

This is assuming you really don't want a lisp-like view

menutree = [
  "The Universe", f1, [
    "Our Galaxy", f2, [
      "Milky Way", f3, [
        "Solar System", f4, [
      "Andromeda", f5, [],

which is essentially one small step removed from the mini-language
and has a simple recursive conversion function.  You'll need to tweak
it somewhat if you want to add user-defined names for the nodes.
I left out parens for the terms, using an implicit group-of-three, since
that makes it look less lisp like ;)

You can even consider the even more exotic

class universe:
  fields = Info("The Universe", f1)
  class galaxy:
    info = Info("Milky Way", f2)
    class solarSystem:
      info = Info("Solar System", f3)
  class andromeda:
    info = Info("Andromeda", f5)

with a converter function which inspects bits of internals to
figure things out, like

class Info:
  def __init__(self, text, f):
    self.text = text
    self.f = f
    self.lineno = sys._getframe(1).f._lineno

def convert(tree, klass):
  root_name = klass.__name__
  .. make the root node ...
  .. start some recusrive routine which uses ...
  subklasses = [subklass for subklass in klass.__dict__.items()
                              if inspect.isclass(subklass)]
  # sort them then in the order of definition
  subklasses.sort(lambda x, y: cmp(x.info.lineno, y.info.lineno))

Of these, I prefer the getattr/setattr version.

                    dalke at dalkescientific.com

More information about the Python-list mailing list