On 13/03/06, Kent Johnson <[EMAIL PROTECTED]> wrote:
> Ed Singleton wrote:
> > On 10/03/06, Kent Johnson <[EMAIL PROTECTED]> wrote:
> >
> >>Ed Singleton wrote:
> >>>I want to use this in a few different places.  For example Faces, the
> >>>Python Project Management Planner Tool Thingy, uses nested functions
> >>>to put tasks within a project:
> >>>
> >>>def MyProject():
> >>>    start = "2006-03-06"
> >>>    resource = Me
> >>>
> >>>    def Task1():
> >>>        start = "2006-03-13"
> >>>
> >>>    def Task2():
> >>>        effort = "1w"
> >>>
> >>>I'd like to load these from a database (using SQLObject), but I'm not
> >>>sure how I can define the name of the function from a filed in a
> >>>database (or read in from a text file).
> >>
> >>This is truly bizarre use of nested functions. Faces must be looking at
> >>the compiled function objects to pick this out.
> >
> >
> > To be honest, this didn't seem that bizarre to me.  If I understand
> > properly (which I probably don't) functions are just callable objects
> > like any other callable object (or at least can be treated as such).
> > Isn't this just a handy way of creating a nested object structure
> > that's readable?
>
> Why not just use nested dicts?
>
> MyProject = dict(
>    start = "2006-03-06",
>    resource = Me,
>    Task1 = dict(start = "2006-03-13"),
>    Task2 = dict(effort = "1w"),
> )
>
> Maybe the appearance isn't quite as nice but the intent is clear, the
> code to access the data is *much* simpler, and it lends itself to the
> kind of programmatic creation you are trying to do. Take a look at
> task.Task._compile() in the faces source to see the gyrations it takes
> to extract the data in functional form. The Zen of Python says,
>    "Explicit is better than implicit"
>    "Simple is better than complex"

Point taken.  Dict's are easier.  And the appearance is fine.

I've just discovered with a little playing, that you can do:

>>> def z(v):
...     def f(x):
...             print x * v
...     return f
...
>>> c = z(3)
>>> c(1)
3
>>> funcdict = dict(foo = z(4))
>>> funcdict["foo"](1)
4

Which was obvious enough that I thought of trying it, but surprising
enough that I was really pleased when it worked.

> >>In general you can set an attribute of an object using setattr():
> >>   setattr(foo, 'bar', 3)
> >>is the same as
> >>   foo.bar = 3
> >>but the attribute name is specified as a string so it can be determined
> >>at runtime.
> >
> >
> > This makes sense, and I think I can see how I would use it.
> >
> > To create a bunch of objects from some data (just name and start date):
> >
> > for fname, startdate in data:
> >     def foo:
> >         start = ""
> >     setattr(foo, __name__, fname)
> >     setattr(foo, start, startdate)
> >
> > Sorting out the nesting should be fairly straightforward (if the above 
> > works).
>
> No, it won't work. A function attribute is not the same as a local
> variable of the function. What you propose is essentially
> def foo(): pass
> foo.bar = 'data'
>
> but what you need is
> def foo():
>    bar = 'data'
>
> which is very different.
>
> faces looks at foo.func_code.co_names to find the names you have used,
> and it actually runs the function with a tracing hook to capture the values.
>
> There doesn't seem to be any other way to define a Task in faces,
> either. You have to actually create functions. I guess this might be a
> good place to use exec - just create the source code for the function
> defs in a string and exec it, then retrieve the function from the global
> namespace and pass it to faces. Then tell me why this API is better than
> using nested dicts.

Agreed, though to be fair the author of faces has probably
overcomplicated the code for handling it (which is a damn shame as it
is really quite a nice project planning tool).  I guess you can't
blindly iterate over the methods of functions, as there are other
methods there that you might not want to use (like setattr and stuff,
maybe?).

Ed
_______________________________________________
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor

Reply via email to