Frage

Ich will Klasse atttributes zu einer Super dynamisch hinzuzufügen. Darüber hinaus möchte ich Klassen erstellen, dass erben von dieser übergeordneten Klasse dynamisch, und der Name dieser Subklassen von Benutzereingaben abhängen sollte.

Es gibt eine übergeordnete Klasse „Einheit“, zu denen ich Attribute zur Laufzeit hinzufügen. Diese bereits funktioniert.

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)

Dies führt zu dem gewünschten Ausgang:
Strenght ofmyarcher: 5
Strenght ofmyarcher: 2

Aber jetzt will ich nicht die Unterklasse Archer vordefinieren, aber ich möchte lieber der Benutzer entscheiden lassen, wie diese Unterklasse nennen. Ich habe so etwas wie dies versucht:

class Meta(type, subclassname):
    def __new__(cls, subclassname, bases, dct):
    return type.__new__(cls, subclassname, Unit, dct)

factory = Meta()    
factory.__new__("Soldier")  

aber kein Glück. Ich glaube, ich habe nicht wirklich verstanden, was neue hier der Fall ist. Was ich als Ergebnis will hier ist

class Soldier(Unit):
    pass

wird vom Werk geschaffen. Und wenn ich das Werk mit dem Argument „Knight“ nennen, würde ich eine Klasse Ritter mögen, Unterklasse der Einheit, geschaffen werden.

Irgendwelche Ideen? Vielen Dank im Voraus!
Bye
-Sano

War es hilfreich?

Lösung

Um eine Klasse von einem Namen zu erstellen, verwenden Sie die class Anweisung und den Namen zuweisen. Beachten Sie:

def meta(name):
    class cls(Unit):
        pass

    cls.__name__ = name
    return cls

Nun nehme ich an, ich soll mich erklären, und so weiter. Wenn Sie eine Klasse erstellen, die Klasse Anweisung verwendet wird, wird es getan dynamically-- es Äquivalent des Aufrufs ist type() .

Zum Beispiel die folgenden zwei Schnipsel das gleiche tun:

class X(object): pass
X = type("X", (object,), {})

Der Name einer class-- das erste Argument type-- zu __name__ zugeordnet ist, und das ist im Grunde das Ende, dass (das einzige Mal __name__ selbst verwendet wird, ist wahrscheinlich in der Standard-__repr__() Implementierung). Um eine Klasse mit einem dynamischen Namen zu erstellen, können Sie in der Art der Tat Aufruf wie so, oder Sie können nur die Klassennamen später ändern. Die class Syntax besteht aus einem Grund, though-- es bequem ist, und es ist einfach später zu und ändern die Dinge hinzuzufügen. Wenn Sie wollen Methoden hinzufügen, zum Beispiel, wäre es

class X(object):
    def foo(self): print "foo"

def foo(self): print "foo"
X = type("X", (object,), {'foo':foo})

und so weiter. Also habe ich die Klasse statement-- verwenden würde Ihnen raten, wenn Sie gewusst hätte man so von Anfang an tun könnten, würden Sie wahrscheinlich getan haben. Der Umgang mit type und so weiter ist ein Chaos.

(Sie soll nicht durch die Art und Weise, Call type.__new__() von Hand, nur type())

Andere Tipps

Haben Sie einen Blick auf die type() eingebaute Funktion.

knight_class = type('Knight', (Unit,), {})
  • Erster Parameter: Name der neuen Klasse
  • Zweiter Parameter: Tuple von Elternklassen
  • Dritter Parameter:. Wörterbuch der Klasse Attribute

Aber in Ihrem Fall, wenn die Unterklassen vielleicht nicht ein anderes Verhalten implementieren, der Unit Klasse Attribut eines name geben ausreichend.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top