如何为python类型的对象实现默认的__repr__?

时间:2019-02-06 19:21:09

标签: python

假设我创建一个新类作为元类的一部分:

import six

class Meta(type):
    def __new__(mcl, name, bases, attrs):
        nt = type.__new__(mcl, name, bases, attrs)

        class NestedClass(object):
            pass
        print(NestedClass)

        return nt

class Foo(six.with_metaclass(Meta), object):
    pass

在Python 2中,我得到: <class '__main__.NestedClass'> 而在Python 3中,我得到: <class '__main__.Meta.__new__.<locals>.NestedClass'>

我知道我可以通过在__repr__()上实现自己的版本来控制Meta的行为,例如:

class Meta(type):
    # ...
    def __repr__(self):
        return "<class '{}'>.format(self.__name__)"

但是,我最好奇的是默认Python 3版本在调用时从哪里获得“ __main__.Meta.__new__.<locals>.”。检查类对象,我看不到任何存储它的状态。它是否直接融入__repr__()函数本身中?

1 个答案:

答案 0 :(得分:2)

这来自__module____qualname__的组合(通过PEP 3155在python3中新增)

稍微调整您的示例:

import six

class Meta(type):
    def __new__(mcl, name, bases, attrs):
        nt = type.__new__(mcl, name, bases, attrs)

        class NestedClass(object):
            pass
        print(NestedClass)
        # vvvvvvvvvvvvvvvvvvvvvvvvvvvvv
        print(NestedClass.__module__)
        print(NestedClass.__qualname__)
        # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

        return nt

class Foo(six.with_metaclass(Meta), object):
    pass

产生以下输出:

$ python3 t.py 
<class '__main__.Meta.__new__.<locals>.NestedClass'>
__main__
Meta.__new__.<locals>.NestedClass

请注意,python 2.x没有__qualname__,因此您需要使用getattr(cls, '__qualname__', '__name__')之类的内容进行调整才能兼容