tags:

views:

75

answers:

3

Say I have the following code:

 from foo.bar import Foo
 from foo.foo import Bar

 __all__ = ["Foo", "Bar"]

 def iterate_over_all():
     ...

How can I implement code in the function iterate_over_all() that can dynamically obtain references to whatever is referenced in __all__ the module where the function is implemented? IE: in iterate_over_all() I want to work with foo.bar.Foo and foo.foo.Bar.

A: 

eval is one way. e.g. eval("Foo") would give you Foo. However you can also just put Foo and Bar directly in your list e.g. __all__ = [Foo, Bar]

It would depend on where the contents of __all__ is coming from in your actual program.

mikej
Hi Mike, yes this would work but according to the docs these should be strings: "he import statement uses the following convention: if a package’s __init__.py code defines a list named __all__, it is taken to be the list of module names that should be imported when from package import * is encountered." (http://docs.python.org/tutorial/modules.html?highlight=__all__)
jkp
Thanks for the link. Would looking the items up in globals() work? e.g. globals()["Foo"]
mikej
@mikej Yes, I would say so, see Martin's answer.
ThomasH
A: 

You can easily index with the strings from __all__ into the module's __dict__:

__dict__["Foo"] == foo.bar.Foo  # -> True
ThomasH
Thomas: great answer, but how to get a reference to that module's dict?
jkp
Ah, I thought *\_\_dict\_\_* would be available right away... Here is a way to get it: *sys.modules[globals()[\_\_name\_\_]].\_\_dict\_\_*. (Gee, I wished there was a *self* on the module level ...).
ThomasH
It's actually funny that other module attributes are freely available, like *\_\_name\_\_* and *\_\_file\_\_*, while *\_\_dict\_\_* is not...
ThomasH
Indeed it is! I was puzzled by that.
jkp
+2  A: 

Would this do?

def iterate_over_all():
    for name in __all__:
        value = globals()[name]
        yield value # or do whatever with it
martin
You're right, *globals()* is actually nicer than trying to get to *\_\_dict\_\_*, and for the purpose of this question it seems to have the same keys with the right references.
ThomasH