multiple namespaces within a single module?
Arnaud Delobelle
arnodel at gmail.com
Fri Feb 10 05:41:06 EST 2012
On 10 February 2012 00:05, Ethan Furman <ethan at stoneleaf.us> wrote:
> Ethan Furman wrote:
>>
>> Hrm -- and functions/classes/etc would have to refer to each other that
>> way as well inside the namespace... not sure I'm in love with that...
>
>
>
> Not sure I hate it, either. ;)
>
> Slightly more sophisticated code:
>
> <code>
> class NameSpace(object):
> def __init__(self, current_globals):
> self.globals = current_globals
> self.saved_globals = current_globals.copy()
>
> def __enter__(self):
> return self
> def __exit__(self, *args):
> new_items = []
> for key, value in self.globals.items():
> if (key not in self.saved_globals and value is not self
> or key in self.saved_globals
> and value != self.saved_globals[key]):
>
> new_items.append((key, value))
> for key, value in new_items:
> setattr(self, key, value)
> del self.globals[key]
> self.globals.update(self.saved_globals)
>
> if __name__ == '__main__':
> x = 'inside main!'
> with NameSpace(globals()) as a:
> x = 'inside a?'
> def fn1():
> print(a.x)
> with NameSpace(globals()) as b:
> x = 'inside b?'
> def fn1():
> print(b.x)
> def fn2():
> print('hello!')
> b.fn1()
> y = 'still inside main'
> a.fn1()
> b.fn1()
> print(x)
> print(y)
> </code>
Please! Metaclasses are the obvious way to proceed here :) Then there
is no need for the 'a.x' and 'b.x' cruft.
marigold:junk arno$ cat namespace.py
function = type(lambda:0)
def change_globals(f, g):
return function(f.__code__, g, f.__name__, f.__defaults__, f.__closure__)
class MetaNamespace(type):
def __new__(self, name, bases, attrs):
attrs['__builtins__'] = __builtins__
for name, value in attrs.items():
if isinstance(value, function):
attrs[name] = change_globals(value, attrs)
return type.__new__(self, name, bases, attrs)
class Namespace(metaclass=MetaNamespace):
pass
x = "inside main"
class a(Namespace):
x = "inside a"
def fn1():
print(x)
class b(Namespace):
x = "inside b"
def fn1():
print(x)
def fn2():
print("hello")
fn1()
y = "inside main"
a.fn1()
b.fn1()
b.fn2()
print(x)
print(y)
marigold:junk arno$ python3 namespace.py
inside a
inside b
hello
inside b
inside main
inside main
A bit more work would be needed to support nested functions and closures...
--
Arnaud
More information about the Python-list
mailing list