我可以为类而不是实例定义 __repr__ 吗?

发布于 2024-12-28 12:07:59 字数 422 浏览 5 评论 0原文

我可以为类而不是实例定义 __repr__ 吗?例如,我正在尝试执行此操作,

class A(object):
    @classmethod
    def __repr__(cls):
        return 'My class %s' % cls

我得到的是

In [58]: a=A()

In [59]: a
Out[59]: My class <class '__main__.A'>

In [60]: A
Out[60]: __main__.A

我正在尝试使第 60 行的输出看起来像“My Class A”,而不是实例 a。我想这样做的原因是我正在使用 Python 的元类生成很多类。我想要一种比库存代表更易读的方式来识别类别。

Can I define a __repr__ for a class rather than an instance? For example, I'm trying to do this

class A(object):
    @classmethod
    def __repr__(cls):
        return 'My class %s' % cls

What I get is

In [58]: a=A()

In [59]: a
Out[59]: My class <class '__main__.A'>

In [60]: A
Out[60]: __main__.A

I'm trying to get the output of line 60 to look like "My Class A", not for the instance a. The reason I want to do this is I'm generating a lot of classes using Python's metaclass. And I want a more readable way to identify the class than the stock repr.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

转瞬即逝 2025-01-04 12:07:59

您需要在元类上定义__repr__

class Meta(type):
    def __repr__(cls):
        return 'My class %s' % cls.__name__

class A(object):
    __metaclass__ = Meta

__repr__ 返回对象实例的表示形式。因此,通过在 A 上定义 __repr__,您可以指定 repr(A()) 的外观。

要定义类的表示,您需要定义 type 实例的表示方式。在这种情况下,请将 type 替换为根据需要定义的 __repr__ 的自定义元类。

>> repr(A)
My class A

如果你想为每个类定义一个自定义的 __repr__ ,我不确定是否有一种特别干净的方法来做到这一点。但你可以做这样的事情。

class Meta(type):
    def __repr__(cls):
        if hasattr(cls, '_class_repr'):
            return getattr(cls, '_class_repr')()
        else:
            return super(Meta, cls).__repr__()

class A(object):
    __metaclass__ = Meta

    @classmethod
    def _class_repr(cls):
        return 'My class %s' % cls.__name__

class B(object):
    __metaclass__ = Meta

然后您可以根据每个班级进行自定义。

>> repr(A)
My class A
>> repr(B)
<__main__.B object at 0xb772068c>

You need to define __repr__ on the metaclass.

class Meta(type):
    def __repr__(cls):
        return 'My class %s' % cls.__name__

class A(object):
    __metaclass__ = Meta

__repr__ returns a representation of an instance of an object. So by defining __repr__ on A, you're specifying what you want repr(A()) to look like.

To define the representation of the class, you need to define how an instance of type is represented. In this case, replace type with a custom metaclass with __repr__ defined as you need.

>> repr(A)
My class A

If you want to define a custom __repr__ for each class, I'm not sure there's a particularly clean way to do it. But you could do something like this.

class Meta(type):
    def __repr__(cls):
        if hasattr(cls, '_class_repr'):
            return getattr(cls, '_class_repr')()
        else:
            return super(Meta, cls).__repr__()

class A(object):
    __metaclass__ = Meta

    @classmethod
    def _class_repr(cls):
        return 'My class %s' % cls.__name__

class B(object):
    __metaclass__ = Meta

Then you can customize on a per-class basis.

>> repr(A)
My class A
>> repr(B)
<__main__.B object at 0xb772068c>
放肆 2025-01-04 12:07:59

我可以为类而不是实例定义 __repr__ 吗?

当然,我在这里用通过 repr 测试的 __repr__ 进行演示。

class Type(type):
    def __repr__(cls):
        """
        >>> Type('Baz', (Foo, Bar,), {'__module__': '__main__', '__doc__': None})
        Type('Baz', (Foo, Bar,), {'__module__': '__main__', '__doc__': None})
        """
        name = cls.__name__
        parents = ', '.join(b.__name__ for b in cls.__bases__)
        if parents:
            parents += ','
        namespace = ', '.join(': '.join(
          (repr(k), repr(v) if not isinstance(v, type) else v.__name__)) 
               for k, v in cls.__dict__.items())
        return 'Type(\'{0}\', ({1}), {{{2}}})'.format(name, parents, namespace)

    def __eq__(cls, other):
        return (cls.__name__, cls.__bases__, cls.__dict__) == (
                other.__name__, other.__bases__, other.__dict__)

并演示:

class Foo(object): pass

class Bar(object): pass

Python 2:

class Baz(Foo, Bar): 
    __metaclass__ = Type

或者 Python 3:

class Baz(Foo, Bar, metaclass=Type): 
    pass

或者相当普遍:

Baz = Type('Baz', (Foo, Bar), {})
>>> Baz
Type('Baz', (Foo, Bar,), {'__module__': '__main__', '__doc__': None})

并且进行 repr 测试:

def main():
    print Baz
    assert Baz == eval(repr(Baz))

什么是 repr 测试?这是来自 repr 文档的上述测试:

>>> help(repr)
Help on built-in function repr in module __builtin__:

repr(...)
    repr(object) -> string

    Return the canonical string representation of the object.
    For most object types, eval(repr(object)) == object.

Can I define a __repr__ for a class rather than an instance?

Sure, I demonstrate here, with a __repr__ that passes the repr test.

class Type(type):
    def __repr__(cls):
        """
        >>> Type('Baz', (Foo, Bar,), {'__module__': '__main__', '__doc__': None})
        Type('Baz', (Foo, Bar,), {'__module__': '__main__', '__doc__': None})
        """
        name = cls.__name__
        parents = ', '.join(b.__name__ for b in cls.__bases__)
        if parents:
            parents += ','
        namespace = ', '.join(': '.join(
          (repr(k), repr(v) if not isinstance(v, type) else v.__name__)) 
               for k, v in cls.__dict__.items())
        return 'Type(\'{0}\', ({1}), {{{2}}})'.format(name, parents, namespace)

    def __eq__(cls, other):
        return (cls.__name__, cls.__bases__, cls.__dict__) == (
                other.__name__, other.__bases__, other.__dict__)

And to demonstrate:

class Foo(object): pass

class Bar(object): pass

Either Python 2:

class Baz(Foo, Bar): 
    __metaclass__ = Type

Or Python 3:

class Baz(Foo, Bar, metaclass=Type): 
    pass

Or fairly universally:

Baz = Type('Baz', (Foo, Bar), {})
>>> Baz
Type('Baz', (Foo, Bar,), {'__module__': '__main__', '__doc__': None})

And to do the repr test:

def main():
    print Baz
    assert Baz == eval(repr(Baz))

What is the repr test? It's the above test from the documentation on repr:

>>> help(repr)
Help on built-in function repr in module __builtin__:

repr(...)
    repr(object) -> string

    Return the canonical string representation of the object.
    For most object types, eval(repr(object)) == object.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文