Quiero añadir atttributes clase a una superclase de forma dinámica. Por otra parte, quiero crear clases que heredan de esta superclase de forma dinámica, y el nombre de las subclases debe depender de la entrada del usuario.Python: generador de clases usando la entrada del usuario como nombres de clase
hay una "Unidad" superclase, a la cual puedo añadir atributos en tiempo de ejecución. Esto ya funciona
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)
Esto conduce a la salida deseada:
Fuerza ofmyarcher: 5
Fuerza ofmyarcher: 2
Pero ahora no quiero predefinir la subclase Archer, pero prefiero dejar que la el usuario decide cómo llamar a esta subclase. He intentado algo como esto:
class Meta(type, subclassname):
def __new__(cls, subclassname, bases, dct):
return type.__new__(cls, subclassname, Unit, dct)
factory = Meta()
factory.__new__("Soldier")
pero no hubo suerte. Creo que realmente no han entendido lo que nueva hace aquí. Lo que quiero como resultado aquí es
class Soldier(Unit):
pass
siendo creado por la fábrica. Y si llamo a la fábrica con el argumento de "Caballero", me gustaría un caballero de clase, subclase de Unidad, que se creará.
¿Alguna idea? ¡Muchas gracias de antemano!
adiós
-Sano
Gracias Devin! Tanto su solución como la de Félix parecen tener un efecto secundario que no he considerado: la nueva clase es un objeto y debe engancharse a algo, almacenada en un varibale o añadida a una lista o algo. No puedo simplemente crear la clase Knight y luego llamar al constructor con myKnight = Knight(). Por el contrario, tengo que hacer algo como esto: unitlist.append (meta ("Knight")) myKnight = unitlist [0]() ¿Hay alguna manera de hacerlo? Para decirlo sin rodeos: Guarde la clase Knight en la misma "posición general" en la que se guarda la clase de la Unidad cuando se alcanza su definición en el código. – Sano98
@ Sano98: Realmente no estoy seguro de lo que quieres decir. Puedes hacer 'Knight = meta (" Knight ")' y luego hacer 'myKnight = Knight()'. ¿Qué quieres exactamente? –
¡Gracias, eso es exactamente lo que quiero hacer! Simplemente guárdalo debajo de Knight ... Y luego está en el espacio de nombres global y puedo usar la clase como si estuviera codificada. Genial, gracias. Simplemente no pensé que podría llamar a Knight() al guardar la clase como Knight, pero claro, ¿por qué no? – Sano98