Dynamic creation of an object instance of a class by name

Peter Otten __peter__ at web.de
Wed Apr 7 12:46:32 EDT 2004


Diez B. Roggisch wrote:

>> Don't listen to the voices whispering "Use eval()" or "globals() are the
>> way to go", make it clean and explicit with a dictionary containing all
>> classes you want to expose:
> 
> Out of curiosity - why not to use eval? having a dict like yours makes
> things look like your average java factory pattern - some explicit
> structure, to which access has to be guaranteed and that requires a
> registration.
> 
> Of course, if you know that you will always only select the class from a
> fixed num of classes, your approach ensures that no non-compliant classes
> can be selected - but hey, we're dynamic here ;) You never can be totally
> sure what you get....

It's probably a matter of taste, but most of the time the use of eval()
suggests more freedom than there actually is. Let's suppose there are 3
classes A, B, and C that will be used by your eval(), that limitation may
then be enforced in various parts of your code or in the documentation,
while I tend to see exposed = dict(...) as self-documenting. You can go to
the implementation of one class in the list to look up the interface.

To take an (almost) real-world example from the library, what would you
suppose the following to do?

klass = eval(klass, vars(logging))

What would you do to make the above accept your special-purpose handler
class? I think something like

availableHandlers = {...}

def registerHandler(name, klass, replace=False):
    if not replace and name in availableHandlers:
        raise NameClash    
   availableHandlers[name] = klass

formatterClass = availableHandlers[name]

is much clearer.

As a side note (not that I think this is important here), eval() is not the
fastest of functions:

$ timeit.py -s"class A: pass" -s"all=dict(A=A)" "all['A']"
10000000 loops, best of 3: 0.147 usec per loop
$ timeit.py -s"class A: pass" "eval('A')"
10000 loops, best of 3: 19.7 usec per loop


Peter




More information about the Python-list mailing list