Класс __repr__ метакласса, а не класс - PullRequest
0 голосов
/ 19 сентября 2018

Мне известно о возможности определения '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 и т. Д. Вызов типа в экземплярах работает просто отлично, но так какТип также может быть вызван в классе, мне нужна более удобная для пользователя возвращаемая строка.

Ответы [ 2 ]

0 голосов
/ 20 сентября 2018

На самом деле, ничто не помешает вам написать класс мета-мета с __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 голосов
/ 19 сентября 2018

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

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
...