元类的类 __repr__,而不是类

Posted

技术标签:

【中文标题】元类的类 __repr__,而不是类【英文标题】:Class __repr__ of a metaclass, not a class 【发布时间】:2019-02-23 10:44:12 【问题描述】:

我知道使用元类定义'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__,因为我使用的实际实现由一个基类TypeStringNumber 等子类组成。在实例上调用类型就可以了,但是因为type 也可以在类上调用,我需要一个更“用户友好”的返回字符串。

【问题讨论】:

【参考方案1】:

实际上,没有什么可以阻止您使用 __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 继承,而是将其作为它的元类)。

【讨论】:

你能添加repr(M)的输出吗?这是我正在寻找的部分。 @NChauhan 你应该养成自己检查这些东西的习惯。无论如何,当我运行它时,我看到 repr(M)"&lt;metaclass M" 创意!我应该检查一下 :-) Python 元类毕竟还是类。【参考方案2】:

找到了一个简单的解决方案。由于我的类结构(继承树)如下,我只需要向下返回下一个类:

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

【讨论】:

以上是关于元类的类 __repr__,而不是类的主要内容,如果未能解决你的问题,请参考以下文章

python 的元类

元类的“__init_subclass__”方法在此元类构造的类中不起作用

按类型创建的类的python元类

派生类的类/元类方法装饰器

面向对象,元类,控制类,对象的创建

Python-元类 单例