Namespace hack
Daniel Fetchinson
fetchinson at googlemail.com
Thu May 24 09:04:34 EDT 2012
> >From the Zen of Python ("import this"):
>
> Namespaces are one honking great idea -- let's do more of those!
>
>
> Inspired by this, I have a decorator that abuses function closures to
> create a namespace type with the following properties:
>
> - all methods are static methods that do not take a "self" parameter;
>
> - methods can see "class variables";
>
> - external callers can see selected methods and attributes.
>
>
> An example may make this clearer.
>
> In a regular class:
>
> class C:
> x = 42
> def spam(self, y):
> return self.x + y
> def ham(self, z):
> return self.spam(z+1)
>
>
> Notice that the class attribute x is visible to the outside caller, but
> methods spam and ham cannot see it except by prefixing it with a
> reference to "self".
>
> Here's an example using my namespace hack example:
>
> @namespace
> def C(): # Abuse nested functions to make this work.
> x = 42
> def spam(y):
> return x + y
> def ham(z):
> return spam(z+1)
> return (spam, ham) # Need an explicit return to make methods visible.
>
> However, class attribute x is not exposed. You may consider this a
> feature, rather than a bug. To expose a class attribute, define it in the
> outer function argument list:
>
> @namespace
> def C(x=42):
> def spam(y):
> return x + y
> def ham(z):
> return spam(z+1)
> return (spam, ham)
>
>
>
> And in use:
>
>>>> C.x
> 42
>>>> C.spam(100)
> 142
>>>> C.ham(999)
> 1042
>
>
>
> Here's the namespace decorator:
>
> import inspect
>
> def namespace(func):
> spec = inspect.getargspec(func)
> ns = {'__doc__': func.__doc__}
> for name, value in zip(spec.args, spec.defaults or ()):
> ns[name] = value
> function = type(lambda: None)
> exported = func() or ()
> try:
> len(exported)
> except TypeError:
> exported = (exported,)
> for obj in exported:
> if isinstance(obj, function):
> ns[obj.__name__] = staticmethod(obj)
> else:
> raise TypeError('bad export')
> Namespace = type(func.__name__, (), ns)
> return Namespace()
>
>
> Have fun!
Funny, you got to the last line of "import this" but apparently
skipped the second line:
Explicit is better than implicit.
And you didn't even post your message on April 1 so no, I can't laugh
even though I'd like to.
Cheers,
Daniel
--
Psss, psss, put it down! - http://www.cafepress.com/putitdown
More information about the Python-list
mailing list