【问题标题】:Class __repr__ of a metaclass, not a class元类的类 __repr__,而不是类
【发布时间】: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 也可以在类上调用,我需要一个更“用户友好”的返回字符串。

【问题讨论】:

    标签: python python-3.x oop metaclass repr


    【解决方案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
    

    【讨论】:

      猜你喜欢
      • 2019-04-05
      • 2012-02-15
      • 2018-07-30
      • 2020-04-25
      • 2016-04-05
      • 2017-03-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多