Python: Фабрика классов с помощью ввода данных пользователем в качестве имен классов

Я хочу добавить, что класс приписывает суперклассу динамично. Кроме того, я хочу создать классы, которые наследовались этому суперклассу динамично, и название тех подклассов должно зависеть от ввода данных пользователем.

Существует суперкласс "Единица", к которой я могу добавить атрибуты во времени выполнения. Это уже работает.

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

11
задан Facundo Casco 5 May 2012 в 20:47
поделиться

2 ответа

Чтобы создать класс из имени, используйте оператор 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 () )

14
ответ дан 3 December 2019 в 05:33
поделиться

Посмотрите на type() встроенную функцию.

knight_class = type('Knight', (Unit,), {})
  • Первый параметр: Имя нового класса
  • Второй параметр: Кортеж родительских классов
  • Третий параметр: словарь атрибутов класса.

Но в вашем случае, если подклассы не реализуют другое поведение, возможно, достаточно дать классу Unit атрибут name.

7
ответ дан 3 December 2019 в 05:33
поделиться
Другие вопросы по тегам:

Похожие вопросы: