> >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
-- 
http://mail.python.org/mailman/listinfo/python-list

Reply via email to