[Q] python vs checker.py maxlocals
Andrew Dalke
adalke at mindspring.com
Wed Mar 26 22:08:02 EST 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
language
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.
Andrew
dalke at dalkescientific.com
More information about the Python-list
mailing list