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

AltStyle によって変換されたページ (->オリジナル) /