two new wrinkles to the general class!

Jeff Shannon jeff at ccvcorp.com
Thu Nov 4 15:27:52 EST 2004


syd wrote:

>One final question that I can't seem to get, but I know I should be
>able to do:
>
>Given a Library class with possible component class types Nation_A,
>Nation_B, and so forth where type(Nation_A)<>type(Nation_B).  If I had
>the string 'Nation_B', how could I get an empty class Nation_B?
>
>ie,
>dir()=['Library','Nation_A','Nation_B',...]
>desiredEmptyClassString=dir[2]
>desiredEmptyClass=getEmptyClassFromString(desiredEmptyClassString)
>Does a "getEmptyClassFromString" method exist?
>  
>

Not directly, but it can be faked.

It's easiest if you're getting the class from an imported module.  
Remember that a module is just another object, and a class object is 
just another callable.

    import MyLibrary
   
    desired_class = getattr(MyLibrary, desired_empty_class_string)
    myobject = desired_class()

It's a bit trickier if the class is defined in the current module, but 
the principle is similar.  You just need a way to look up an attribute 
in the *current* module's namespace, rather than in another module's 
namespace.  As it turns out, the globals() built-in function will return 
the current global namespace, which is actually a dictionary.

    desired_class = globals()[desired_empty_class_string]
    myobject = desired_class()

Personally, I feel nervous any time I have code that uses something like 
globals() -- I feel like I'm starting to poke at internals.  It should 
be completely safe, especially using it in a read-only way like this, 
but just out of inherent cautiousness I prefer to avoid it when I can.  
So, I'd be likely to put all of the interesting class objects into my 
own dict, and call them from there.

    LibraryFactory = { 'Library': Library, 'Nation_A':Nation_A, ... }

    myobject = LibraryFactory[desired_empty_class_string]()

Note that, if you really are selecting the string via an integer index 
into a list, you could instead key this dictionary off of the integers:

    LibraryFactory = {0:Library, 1:Nation_A, 2:Nation_B, ...}
    myobject = LibraryFactory[index]()

Using a dict like this makes me feel a bit more comfortable than using 
globals() (though I realize that this is not necessarily a matter of 
rational reasoning), and it also seems to me to be a bit more 
encapsulated (relevant items are specifically gathered in one particular 
place, rather than just being scattered about the global namespace and 
picked up as needed).  But using globals() is a perfectly viable option 
as well.

Jeff Shannon
Technician/Programmer
Credit International




More information about the Python-list mailing list