Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #20093 > unrolled thread

multiple namespaces within a single module?

Started byjkn <jkn_gg@nicorp.f9.co.uk>
First post2012-02-09 10:32 -0800
Last post2012-02-10 10:41 +0000
Articles 10 — 4 participants

Back to article view | Back to comp.lang.python


Contents

  multiple namespaces within a single module? jkn <jkn_gg@nicorp.f9.co.uk> - 2012-02-09 10:32 -0800
    Re: multiple namespaces within a single module? Peter Otten <__peter__@web.de> - 2012-02-09 20:33 +0100
      Re: multiple namespaces within a single module? jkn <jkn_gg@nicorp.f9.co.uk> - 2012-02-09 15:24 -0800
        Re: multiple namespaces within a single module? Peter Otten <__peter__@web.de> - 2012-02-10 12:10 +0100
          Re: multiple namespaces within a single module? jkn <jkn_gg@nicorp.f9.co.uk> - 2012-02-10 08:28 -0800
    Re: multiple namespaces within a single module? Ethan Furman <ethan@stoneleaf.us> - 2012-02-09 13:12 -0800
    Re: multiple namespaces within a single module? Peter Otten <__peter__@web.de> - 2012-02-09 22:53 +0100
    Re: multiple namespaces within a single module? Ethan Furman <ethan@stoneleaf.us> - 2012-02-09 14:25 -0800
    Re: multiple namespaces within a single module? Ethan Furman <ethan@stoneleaf.us> - 2012-02-09 16:05 -0800
    Re: multiple namespaces within a single module? Arnaud Delobelle <arnodel@gmail.com> - 2012-02-10 10:41 +0000

#20093 — multiple namespaces within a single module?

Fromjkn <jkn_gg@nicorp.f9.co.uk>
Date2012-02-09 10:32 -0800
Subjectmultiple namespaces within a single module?
Message-ID<6f50fa3d-74e6-4682-b5d8-2634d418dd23@d15g2000yqg.googlegroups.com>
Hello there

    is it possible to have multiple namespaces within a single python
module?

I have a small app which is in three or four .py files. For various
reasons I would like to (perhaps optionally) combine these into one
file. I was hoping that there might be a simple mechanism that would
let me do this and maintain the namespaces referred to: so that the
'combined' file would look something like

#
# not real python
#

# originally from a.py
with namespace a:
    def function():
        pass

# ...

# originally from b.py
with namespace b:
    def function():
        pass

# originally from main module

a.function()
b.function()

etc.

Is there anything like this available?

    Thanks
    J^n

[toc] | [next] | [standalone]


#20099

FromPeter Otten <__peter__@web.de>
Date2012-02-09 20:33 +0100
Message-ID<mailman.5606.1328816021.27778.python-list@python.org>
In reply to#20093
jkn wrote:

>     is it possible to have multiple namespaces within a single python
> module?

Unless you are abusing classes I don't think so.
 
> I have a small app which is in three or four .py files. For various
> reasons I would like to (perhaps optionally) combine these into one
> file. 

Rename your main script into __main__.py, put it into a zip file together 
with the other modules and run that.

[toc] | [prev] | [next] | [standalone]


#20120

Fromjkn <jkn_gg@nicorp.f9.co.uk>
Date2012-02-09 15:24 -0800
Message-ID<2caddc2a-f412-49bc-b02e-d475bc6db8a0@s13g2000yqe.googlegroups.com>
In reply to#20099
Hi Peter

On Feb 9, 7:33 pm, Peter Otten <__pete...@web.de> wrote:
> jkn wrote:
> >     is it possible to have multiple namespaces within a single python
> > module?
>
> Unless you are abusing classes I don't think so.
>
> > I have a small app which is in three or four .py files. For various
> > reasons I would like to (perhaps optionally) combine these into one
> > file.
>
> Rename your main script into __main__.py, put it into a zip file together
> with the other modules and run that.

Hmm ... thanks for mentioning this feature, I didn't know of it
before. Sounds great, except that I gather it needs Python >2.5? I'm
stuck with v2.4 at the moment unfortunately...

    J^n

[toc] | [prev] | [next] | [standalone]


#20157

FromPeter Otten <__peter__@web.de>
Date2012-02-10 12:10 +0100
Message-ID<mailman.5652.1328872247.27778.python-list@python.org>
In reply to#20120
jkn wrote:

> Hi Peter
> 
> On Feb 9, 7:33 pm, Peter Otten <__pete...@web.de> wrote:
>> jkn wrote:
>> > is it possible to have multiple namespaces within a single python
>> > module?
>>
>> Unless you are abusing classes I don't think so.
>>
>> > I have a small app which is in three or four .py files. For various
>> > reasons I would like to (perhaps optionally) combine these into one
>> > file.
>>
>> Rename your main script into __main__.py, put it into a zip file together
>> with the other modules and run that.
> 
> Hmm ... thanks for mentioning this feature, I didn't know of it
> before. Sounds great, except that I gather it needs Python >2.5? I'm
> stuck with v2.4 at the moment unfortunately...

You can import and run explicitly, 

$ PYTHONPATH mylib.zip python -c'import mainmod; mainmod.main()'

assuming you have a module mainmod.py containing a function main() in 
mylib.zip.

[toc] | [prev] | [next] | [standalone]


#20175

Fromjkn <jkn_gg@nicorp.f9.co.uk>
Date2012-02-10 08:28 -0800
Message-ID<fac1f033-31b9-4437-91ec-d7685a6ae436@l16g2000vbl.googlegroups.com>
In reply to#20157
Hi Peter

On Feb 10, 11:10 am, Peter Otten <__pete...@web.de> wrote:

[...]

> > Hmm ... thanks for mentioning this feature, I didn't know of it
> > before. Sounds great, except that I gather it needs Python >2.5? I'm
> > stuck with v2.4 at the moment unfortunately...
>
> You can import and run explicitly,
>
> $ PYTHONPATH mylib.zip python -c'import mainmod; mainmod.main()'
>
> assuming you have a module mainmod.py containing a function main() in
> mylib.zip.

That looks very useful  -thanks for the tip!

    J^n

[toc] | [prev] | [next] | [standalone]


#20113

FromEthan Furman <ethan@stoneleaf.us>
Date2012-02-09 13:12 -0800
Message-ID<mailman.5614.1328823284.27778.python-list@python.org>
In reply to#20093
Peter Otten wrote:
> jkn wrote:
> 
>>     is it possible to have multiple namespaces within a single python
>> module?
> 
> Unless you are abusing classes I don't think so.


Speaking of...

<code>
class NameSpace(object):
     def __init__(self, globals):
         self.globals = globals
         self.current_keys = list(globals.keys())
     def __enter__(self):
         return self
     def __exit__(self, *args):
         new_items = []
         for key, value in self.globals.items():
             if key not in self.current_keys and value is not self:
                 new_items.append((key, value))
         for key, value in new_items:
             setattr(self, key, value)
             del self.globals[key]

if __name__ == '__main__':
     with NameSpace(globals()) as a:
         def function():
             print('inside a!')
     with NameSpace(globals()) as b:
         def function():
             print('inside b!')

     a.function()
     b.function()
     print(vars())
</code>

The NameSpace objects do *not* get their own copy of globals(), but for 
functions, etc., it should work fine.  As a bonus the above code works 
for both 2.x and 3.x.

~Ethan~

[toc] | [prev] | [next] | [standalone]


#20114

FromPeter Otten <__peter__@web.de>
Date2012-02-09 22:53 +0100
Message-ID<mailman.5616.1328824410.27778.python-list@python.org>
In reply to#20093
Ethan Furman wrote:

> Peter Otten wrote:
>> jkn wrote:
>> 
>>>     is it possible to have multiple namespaces within a single python
>>> module?
>> 
>> Unless you are abusing classes I don't think so.
> 
> 
> Speaking of...
> 
> <code>
> class NameSpace(object):
>      def __init__(self, globals):
>          self.globals = globals
>          self.current_keys = list(globals.keys())
>      def __enter__(self):
>          return self
>      def __exit__(self, *args):
>          new_items = []
>          for key, value in self.globals.items():
>              if key not in self.current_keys and value is not self:
>                  new_items.append((key, value))
>          for key, value in new_items:
>              setattr(self, key, value)
>              del self.globals[key]
> 
> if __name__ == '__main__':
>      with NameSpace(globals()) as a:
>          def function():
>              print('inside a!')
>      with NameSpace(globals()) as b:
>          def function():
>              print('inside b!')
> 
>      a.function()
>      b.function()
>      print(vars())
> </code>
> 
> The NameSpace objects do *not* get their own copy of globals(), but for
> functions, etc., it should work fine.  As a bonus the above code works
> for both 2.x and 3.x.

Hm, what about

with NameSpace(globals()) as a:
    x = "inside a!"
    def function():
        print(x)
with NameSpace(globals()) as b:
    x = "inside b!"
    def function():
        print(x)

x = "inside main!"
a.function()
b.function()

[toc] | [prev] | [next] | [standalone]


#20117

FromEthan Furman <ethan@stoneleaf.us>
Date2012-02-09 14:25 -0800
Message-ID<mailman.5618.1328827038.27778.python-list@python.org>
In reply to#20093
Peter Otten wrote:
> Hm, what about
> 
> with NameSpace(globals()) as a:
>     x = "inside a!"
>     def function():
>         print(x)
> with NameSpace(globals()) as b:
>     x = "inside b!"
>     def function():
>         print(x)
> 
> x = "inside main!"
> a.function()
> b.function()
> 
> 

It would have to be `a.x = ...` and `b.x = ...` with corresponding 
`print(a.x)` and `print(b.x)`.

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...

~Ethan~

[toc] | [prev] | [next] | [standalone]


#20121

FromEthan Furman <ethan@stoneleaf.us>
Date2012-02-09 16:05 -0800
Message-ID<mailman.5621.1328831986.27778.python-list@python.org>
In reply to#20093
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>

~Ethan~

[toc] | [prev] | [next] | [standalone]


#20154

FromArnaud Delobelle <arnodel@gmail.com>
Date2012-02-10 10:41 +0000
Message-ID<mailman.5649.1328870470.27778.python-list@python.org>
In reply to#20093
On 10 February 2012 00:05, Ethan Furman <ethan@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

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.python


csiph-web