How to use __all__ ?
Alex Martelli
aleax at aleax.it
Fri Feb 7 04:05:02 EST 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