Update locals()
holger krekel
pyth at devel.trillke.net
Sun Apr 28 10:24:17 EDT 2002
On Sun, Apr 28, 2002 at 08:50:13AM -0500, jepler at unpythonic.net wrote:
> > class filename:
> > """ Abstraction for filename ... """
> > # ...
> >
> > for name in filters._stateful_all:
> > doc=filters.__dict__.get(name,undoc).__doc__.strip()+'\n'
> > exec indentedcode("""
> >
> > def %(name)s (self,*args,**kargs):
> > '''%(doc)s'''
> > return filters.%(name)s (*args,**kargs) (self)
> > """ % locals())
> >
> > # ...
>
> I don't quite see what you're doing here, but you might try something like
> (given nested scopes) (untested):
i dynamically define functions as filename-methods. Assume
name is 'access' you get
def access(self,*args,**kargs):
''' checks filename for a given access-mode... '''
return filters.access (*args,**kargs) (self)
defined right in your class scope. After you imported
the module the methods will be there...
> class filename:
> def __getattr__(self, attr):
> if not hasattr(filters, attr): raise AttributeError, attr
> filter_func = getattr(filters, attr)
> ret = lambda *args, **kargs: filter_func(*args, **kargs)(self)
> ret.__doc__ = getattr(filter_func, __doc__, undoc)
> #setattr(self, attr, ret)
> return ret
I am working a lot interactively (like many others with rlcompleter). Dynamic
constructions like this won't show up. So the ret.__doc__ does not make much sense
here IMHO. help ('filename') won't show it either. Otherwise your version
should work. I don't know if you could handle working with
inspect.getargspec to construct the precise signature, though. This can
be done with the above 'templating' (i didn't bother so far).
> My version will also work properly if "filters" is extended at runtime with
> new attributes... It's reasonbly efficient to construct a function at
> runtime with 'lambda', and you can trade time for space by caching the
> attribute on the instance once it's been computed once
My construction was not about extending filters at run time but about
avoiding redundancies and expressing an adapter pattern at compile
time.
> Of course, given that you always immediately call the instance of the
> filters. function, I don't see why you can't simply write
quoting from the example at the end of my posting:
#...
resultfilters = AND(isfile, nolink, fnmatch('data*'), count)
recursefilter = access('wx')
for dir, fnlist in base.filterwalk( resultfilters, recursefilter ):
#...
Note especially that
recursefilter = access('wx')
does not map to
> class filename:
> def access(self, mode='r'):
You would need an unbound partially initialized class-method.
You could try to use Currying (see ASPN-Cookbook)
but it probably gets difficult if you look at the 'resultfilters'-
line. The AND is a stateful-filter as well and you can because
of the templating also do
fn.AND(isfile,nolink,...)
> There's probably some reason which isn't as apparent in this example as
> some of the more complex ones you've written, though...
The problem is i don't want to explain my filename+filters module
in boring details. I tried to extract the basic templating mechanism
and still provide some context to answer Alex Martellis question
about "Give me ONE use..." (for exec without explicit dictionaries).
I am not saying at all that there is no other solution (see your
own solution). Given the context, my 'templating' does still make a lot of sense
to me. Although it might be considered unusual or even unpythonic
but that's a matter of taste to some degree :-)
holger
More information about the Python-list
mailing list