Я хочу добавить, что класс приписывает суперклассу динамично. Кроме того, я хочу создать классы, которые наследовались этому суперклассу динамично, и название тех подклассов должно зависеть от ввода данных пользователем.
Существует суперкласс "Единица", к которой я могу добавить атрибуты во времени выполнения. Это уже работает.
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)
Это приводит к желаемому выводу:
Strenght ofmyarcher: 5
Strenght ofmyarcher: 2
Но теперь я не хочу предопределять Стрельца подкласса, но я скорее позволил пользователю решить, как назвать этот подкласс. Я попробовал что-то вроде этого:
class Meta(type, subclassname):
def __new__(cls, subclassname, bases, dct):
return type.__new__(cls, subclassname, Unit, dct)
factory = Meta()
factory.__new__("Soldier")
но никакая удача. Я предполагаю, что действительно не понял то, что новый делает здесь. Что я хочу в результате, вот
class Soldier(Unit):
pass
будучи созданным фабрикой. И если бы я называю фабрику с аргументом "Рыцарем", я хотел бы, чтобы класс Рыцарь, подкласс Единицы, был создан.
Какие-либо идеи?Заранее большое спасибо!
До свидания
- Sano
Чтобы создать класс из имени, используйте оператор class
и присвойте имя. Заметьте:
def meta(name):
class cls(Unit):
pass
cls.__name__ = name
return cls
Теперь я полагаю, что должен объясниться и так далее. Когда вы создаете класс с помощью оператора class, это делается динамически - это эквивалентно вызову type ()
.
Например, следующие два фрагмента делают то же самое:
class X(object): pass
X = type("X", (object,), {})
Имя класса - первый аргумент типа - присваивается __ name __
, и это, по сути, конец этого (единственный раз, когда __ name __
используется сам, вероятно, в реализации по умолчанию __ repr __ ()
). Чтобы создать класс с динамическим именем, вы можете на самом деле вызвать type таким образом, или вы можете просто изменить имя класса позже. Синтаксис class
существует не просто так - он удобен, и его легко добавить или изменить позже. Например, если вы хотите добавить методы, это будет
class X(object):
def foo(self): print "foo"
def foo(self): print "foo"
X = type("X", (object,), {'foo':foo})
и так далее. Поэтому я бы посоветовал использовать оператор класса - если бы вы знали, что можете сделать это с самого начала, вы, вероятно, сделали бы это. Работа с типом ,
и т. Д. - беспорядок.
(Вы не должны, кстати, вызывать type .__ new __ ()
вручную, только type ()
)
Посмотрите на type()
встроенную функцию.
knight_class = type('Knight', (Unit,), {})
Но в вашем случае, если подклассы не реализуют другое поведение, возможно, достаточно дать классу Unit
атрибут name
.