Класс __repr__ метакласса, а не класс

1

Я знаю о способности определять 'class repr', используя метакласс. Однако мне нужна функциональность возврата метакласса со своим собственным __repr__ как таковым:

class Meta(type):
    def __repr__(cls):
        return 'Person class: {}'.format(cls.__name__)


class Person(metaclass=Meta):
    def __init__(self, name, age, job):
        self.name = name
        self.job = job
        self.age = age

    def __str__(self):
        return 'Person: {}, {}, {}'.format(self.name,
                                           self.age,
                                           self.job)


class Employee(Person):
    def __init__(self, name, age):
        super(Employee, self).__init__(name, age, 'employee')


class Manager(Person):
    def __init__(self, name, age):
        super(Manager, self).__init__(name, age, 'manager')

m = Manager('bob', 79)
e = Employee('stephen', 25)

Как и ожидалось, type(e) и type(m) возвращают свой соответствующий 'Person class:...', однако, если я нахожу type(Employee), я получаю <class '__main__.Meta'>. Мне нужен этот класс, чтобы иметь свой собственный __repr__ поскольку фактическая реализация, которую я использую, состоит из базового класса Type с подклассами String, Number и т.д. Тип вызова в экземплярах работает просто отлично, но поскольку тип может также вызываться в классе, Мне нужна более удобная для пользователя возвращаемая строка.

Теги:
python-3.x
oop
metaclass
repr

2 ответа

2
Лучший ответ

На самом деле, ничто не помешало бы вам написать мета-мета-класс с __repr__ для самого метакласса:

In [2]: class MM(type):
   ...:     def __repr__(cls):
   ...:         return f"<metaclass {cls.__name__}"
   ...:      

In [3]: class M(type, metaclass=MM):
   ...:     def __repr__(cls):
   ...:         return f"<class {cls.__name__}>"
   ...:     

In [4]: class O(metaclass=M):
   ...:     pass
   ...: 

In [5]: o = O()

In [6]: o
Out[6]: <<class O> at 0x7ff7e0089128>

In [7]: O
Out[7]: <class O>

Выходной сигнал repr(M):

In [8]: repr(M)
Out[8]: '<metaclass M'

(Путаница здесь заключается в том, что type также является метаклассом для самого type, что отражается здесь в том, что M не наследует от MM, а скорее имеет его как его метакласс).

  • 0
    Не могли бы вы добавить вывод repr(M) ? Это та часть, которую я ищу.
  • 0
    @NChauhan Вы должны привыкнуть проверять эти вещи самостоятельно. Независимо от того, когда я запускаю это, я вижу, что repr(M) это "<metaclass M"
Показать ещё 2 комментария
0

Нашел простое решение. Поскольку моя структура класса (дерево наследования) выглядит следующим образом, мне просто нужно вернуть следующий класс:

MetaType: metaclass with __repr__
 |
Type: base class
 |
builtins: e.g. String, Number

Итак, все, что я вложил в свой код, было следующим:

t = type(self.parse(args['object']))
# where 'self.parse' is the parsing method for the argument to my function
# where args['object'] is the object whose type is being returned
if t == MetaType:
    return Type
return t

Ещё вопросы

Сообщество Overcoder
Наверх
Меню