views:

62

answers:

2

I have a python module.

I want to populate some values to it at runtime, how do I do it.

Eg. I have a list,

['A', 'B', 'C']

I am creating there classes with these names, and want them to available as if I created them normally

for el in ['A', 'B', 'C']:
    type(el, (object,), {})
+2  A: 

To create your classes dynamically and make them available in the module mymodule:

import mymodule
for el in ['A', 'B', 'C']:
    setattr(mymodule, el, type(el, (object,), {}))

To create the classes in the current module, use the approach in Mike's answer.

Pär Wieslander
But how would you do this from within `mymodule`?
uswaretech
Check out Mike's answer - all of his suggested approaches should work well.
Pär Wieslander
+4  A: 

I can think of a couple ways to do this... In order of (what I believe to be) best to worst we have:

First, setting attributes on the current module

# The first way I had of grabbing the module:
mod = __import__(__name__, fromlist=['nonempty'])

# From Roger's suggestion:
import sys
mod = sys.modules[__name__]

for name in ['A', 'B', 'C']:
    class_ = type(name, (object, ), {})
    setattr(mod, name, class_)

print A, B, C

Second, setting into the current globals dict:

for name in ['A', 'B', 'C']:
    class_ = type(name, (object, ), {})
    globals()[name] = class_

print A, B, C

Last, using exec (eww):

for name in ['A', 'B', 'C']:
    class_ = type(name, (object, ), {})
    exec "%s = class_" % name

print A, B, C

I have tested all three of these work in a stand alone script (where __name__ == "__main__") and as a module in a larger package.

EDIT: With regards to the discussion of method 1 vs method 2 in the comments, they both do EXACTLY the same thing. The name space of a module is defined in a dict stored on the module (here are the docs). From module level you can get this via globals() and from outside you can access it via attributes, or the __dict__ attribute of the module.

An interactive session to demonstrate:

Python 2.6.4 (r264:75706, Nov  8 2009, 17:35:59) 
[GCC 4.2.1 (Apple Inc. build 5646)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> mod = sys.modules[__name__]
>>> mod.__dict__ is globals()
True
Mike Boers
the second method would get my +1. First one is fishy and third is ewww.
kaizer.se
Why `__import__` instead of `sys.modules[__name__]`?
Roger Pate
@kaizer: The first one is what the OP wants: the classes must be added to the module attributes (and from the module, which still works in this case), not in the globals. It looks like `__import__` still has its uses. I think we all agree on the ewww part though ;-)
RedGlyph
@Roger, good point. I added it to the answer.
Mike Boers