How to use __all__ ?

Alex Martelli aleax at aleax.it
Fri Feb 7 10:05:02 CET 2003


Paul Rubin wrote:

> I have a module, x.py, containing
> 
>    __all__ = ('a',)
>    a = 3
>    b = 5
> 
> Now I run Python:
> 
>     Python 2.2 (#1, Feb 10 2002, 19:16:58)
>     [GCC 2.96 20000731 (Red Hat Linux 7.1 2.96-98)] on linux2
>     Type "help", "copyright", "credits" or "license" for more information.
>     >>> import x
>     >>> x.a
>     3
>     >>> x.b
>     5
>     >>> x.__all__
>     ('a',)
> 
> What's the story?  I thought b was supposed to be invisible, since
> it doesn't appear in x's __all__ list.  Is there some other way to
> get that effect?

__all__ influences what happens on "from x import *", only (absent
__all__, then leading underscores block module-level names from the
"from x import *", instead).  There is no way for a module object
to hide some of its attributes.  You CAN, of course, use tricks in
the body of x.py that change sys.modules['x'] to whatever you want;
but it had better be another object (module or instance of any
class of your choice -- the latter wouldn't work with reload though),
otherwise deleting attribute b from sys.modules['x'] will indeed
delete it from your module object.

To clarify:

a = 3
b = 5

print a, b

import sys
del sys.modules['x'].b

print a, b

importing this x.py gives:

[alex at lancelot caps]$ python -c "import x"
3 5
3
Traceback (most recent call last):
  File "<string>", line 1, in ?
  File "x.py", line 9, in ?
    print a, b
NameError: name 'b' is not defined
[alex at lancelot caps]$

But, we CAN be more clever...:

__all__ = 'a',
def a(): b()
def b(): print 'b!'

a()

import sys, new
thismod = sys.modules['x']
sys.modules['x'] = newmod = new.module('x')
for name in __all__:
    setattr(newmod, name, getattr(thismod, name))

and now:

[alex at lancelot caps]$ python -ic "import x"
b!
>>> dir(x)
['__doc__', '__name__', 'a']
>>> x.a()
b!
>>>


For reasons that currently escape me a reload(x)
gets the "true" module x (?), but if that's a
problem perhaps a workaround can be found too.


Alex





More information about the Python-list mailing list