Python 3: class "template" (функция, возвращающая параметризованный класс)

Я пытаюсь создать функцию, которая передается параметр x и возвращает новый класс C. C должен быть подклассом фиксированного базового класса A, только с одним добавлением: добавляется некоторый атрибут класса и устанавливается равным x.

Другими словами:

class C(A):
  C.p = x # x is the parameter passed to the factory function

Легко ли это сделать? Есть ли какие-либо проблемы, о которых я должен знать?

Ответ 1

Прежде всего, обратите внимание, что термин "класс factory" несколько устарел в Python. Он используется в таких языках, как С++, для функции, которая возвращает динамически типизированный экземпляр класса. У него есть имя, потому что оно выделяется на С++; это не редкость, но это необычно, что полезно придать шаблону имя. В Python, однако, это делается постоянно - это такая основная операция, которую никто не беспокоит, дав ей особое имя.

Также обратите внимание, что класс factory возвращает экземпляры класса, а не сам класс. (Опять же, это потому, что из таких языков, как С++, которые не имеют понятия о возврате объектов класса). Однако вы сказали, что хотите вернуть "новый класс", а не новый экземпляр класса.

Тривиально создать локальный класс и вернуть его:

def make_class(x):
    class C(A):
        p = x
    return C

Ответ 2

Функция type имеет версию с 3 аргументами, которая динамически создает новый класс. Передайте имя, базы и dict, содержащие атрибуты и методы класса.

В вашем случае:

def class_factory(x):
    return type("C", (A,), {"p": x})

Очевидно, вы можете динамически установить имя класса "C", но обратите внимание, что для того, чтобы сделать класс общедоступным, вам также необходимо назначить результат функции переменной. Вы можете сделать это динамически, используя globals()["C"] = ..., или назначить классы для словаря, что угодно.