Generating modul classes with eval

Jeremy Bowers jerf at jerf.org
Wed Feb 2 16:20:41 EST 2005


On Wed, 02 Feb 2005 20:49:07 +0000, Axel Straschil wrote:

You are doing several things wrong.

> I was fooling around with creating classes for a module with eval,

You shouldn't create classes with eval, because you don't need to.

"class" isn't a declaration, it is an executable statement that creates
new classes. We'll get into that momentarily...

> something like:
> 
> MyModule.py:
> 
> class Base:
> 	init(self, name):
> 		self._name = name

Your "init" function needs to be spelled "__init__", or it will not be
automatically called.

You also did not correctly use "def" to create your function. When posting
to the newsgroup, try to use real code that you have actually executed.

> that gives: <class '__main__.A'>, but I want MyModule.A ;-)

No, it won't, since your code has syntax errors in it. Post the code you
actually ran.

That said, "__main__" indicates you ran it in the interactive shell. That
is correct, and won't change. Also, the name printing the class gives is
only very rarely important; overall you shouldn't be using that.

I'll start with giving you this:

-------

import sys
module = sys.modules[__name__]

class Base:
    def __init__(self, name):
        self._name = name

for myclass in ['A', 'B', 'C']:
    class Tmp(Base):
        myname = myclass
        def __init__(self):
            Base.__init__(self, self.myname)

    setattr(module, myclass, Tmp)
    
-------

Note that we don't need eval anywhere.

But I'd suggest that this is more likely what you want:

-------

class Base:
    def __init__(self, name):
        self._name = name

myClasses = {}

for className in ['A', 'B', 'C']:
    class Tmp(Base):
        myname = className
        def __init__(self):
            Base.__init__(self, self.myname)

    myClasses[className] = Tmp
    
-------

Adding things straight to modules is rarely worth it; you're better off
just collecting them somewhere.

There are too many differences to go over here between my code and yours,
so if you have questions, please ask. One of the reasons you don't want
eval is that I had to give up trying to read your class code!

Finally, while such generated classes do have their use, I'd ask what you
are planning to do with this; odds are, you don't need it.

In general, unless you are using "eval" to literally execute user supplied
input, you *almost* certainly don't need it.

A downside of my approach is that printing all three classes will say the
class name is "Tmp". Since, as I said, you really shouldn't care about
that, I don't care to try to fix it :-) If you can provide a compelling
reason why you need that, somebody here can help you with that.



More information about the Python-list mailing list