using exec() to instantiate a new object.

Aaron Brady castironpi at
Sat Nov 8 04:20:20 CET 2008

On Nov 7, 4:23 pm, RyanN <Ryan.N... at> wrote:
> Hello,
> I'm trying to teach myself OOP to do a data project involving
> hierarchical data structures.
> I've come up with an analogy for testing involving objects for
> continents, countries, and states where each object contains some
> attributes one of which is a list of objects. E.g. a country will
> contain an attribute population and another countries which is a list
> of country objects. Anyways, here is what I came up with at first:
> NAm = continent('NAm')
> usa= country('usa')
> canada = country('canada')
> mexico = country('mexico')
> florida = state('florida')
> maine = state('maine')
> california = state('california')
> quebec = state('quebec')
> NAm.addCountry(usa)
> NAm.addCountry(canada)
> NAm.addCountry(mexico)
> usa.addState(maine)
> usa.addState(california)
> usa.addState(florida)
> canada.addState(quebec)
> florida.addCounty('dade')
> florida.addCounty('broward')
> maine.addCounty('hancock')
> california.addCounty('marin')

> so this works but is far more cumbersome than it should be.
> I would like to create an object when I add it
> so I wouldn't have to do:
> usa= country('usa')
> NAm.addCountry(usa)
> I could just do
> NAm.addCountry('usa')
> which would first create a country object then add it to a countries
> list

One option is to add the names to a blank object as attributes, using
setattr.  Then you can access them in almost the same way... they're
just in their own namespace.  Other options would be to add them to a
separate dictionary (name -> object).  This example is kind of cool,
as well as nicely instructive.

>>> class Blank: pass
>>> blank= Blank()
>>> class autoname( ):
...     def __init__( self, name ):
...             setattr( blank, name, self )
...    name
>>> autoname( 'fried' )
<__main__.autoname instance at 0x00B44030>
>>> autoname( 'green' )
<__main__.autoname instance at 0x00B44148>
>>> autoname( 'tomatoes' )
<__main__.autoname instance at 0x00B44170>
>>> blank.fried
<__main__.autoname instance at 0x00B44030>
<__main__.autoname instance at 0x00B44148>
>>> blank.tomatoes
<__main__.autoname instance at 0x00B44170>
>>> blank
<__main__.Blank instance at 0x00B40FD0>

You don't have to call the container object 'blank', of course, or its
class for that matter.  I do because that's how it starts out: blank.
Under the hood it's just a plain old dictionary with extra syntax for
accessing its contents.

More information about the Python-list mailing list