I want to add class atttributes to a superclass dynamically. Furthermore, I want to create classes that inherit from this superclass dynamically, and the name of those subclasses should depend on user input.
There is a superclass "Unit", to which I can add attributes at runtime. This already works.
def add_attr (cls, name, value):
setattr(cls, name, value)
class Unit(object):
pass
class Archer(Unit):
pass
myArcher = Archer()
add_attr(Unit, 'strength', 5)
print "Strenght ofmyarcher: " + str(myArcher.strength)
Unit.strength = 2
print "Strenght ofmyarcher: " + str(myArcher.strength)
This leads to the desired output:
Strenght ofmyarcher: 5
Strenght ofmyarcher: 2
But now I don't want to predefine the subclass Archer, but I'd rather let the user decide how to call this subclass. I've tried something like this:
class Meta(type, subclassname):
def __new__(cls, subclassname, bases, dct):
return type.__new__(cls, subclassname, Unit, dct)
factory = Meta()
factory.__new__("Soldier")
but no luck. I guess I haven't really understood what new does here. What I want as a result here is
class Soldier(Unit):
pass
being created by the factory. And if I call the factory with the argument "Knight", I'd like a class Knight, subclass of Unit, to be created.
Any ideas? Many thanks in advance!
Bye
-Sano
Have a look at the
type()
builtin function.But in your case, if the subclasses don't implement a different behaviour, maybe giving the
Unit
class aname
attribute is sufficient.To create a class from a name, use the
class
statement and assign the name. Observe:Now I suppose I should explain myself, and so on. When you create a class using the class statement, it is done dynamically-- it is equivalent of calling
type()
.For example, the following two snippets do the same thing:
The name of a class-- the first argument to type-- is assigned to
__name__
, and that's basically the end of that (the only time__name__
is itself used is probably in the default__repr__()
implementation). To create a class with a dynamic name, you can in fact call type like so, or you can just change the class name afterward. Theclass
syntax exists for a reason, though-- it's convenient, and it's easy to add to and change things later. If you wanted to add methods, for example, it would beand so on. So I would advise using the class statement-- if you had known you could do so from the beginning, you likely would have done so. Dealing with
type
and so on is a mess.(You should not, by the way, call
type.__new__()
by hand, onlytype()
)