2012-01-21 48 views
11

我可以为类而不是实例定义__repr__吗?例如,我试图做到这一点我可以为类而不是实例定义__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的输出,看起来像“我的A级”,而不是实例a。我想这样做的原因是我使用Python的元类生成了很多类。我想要一个更可读的方式来识别类比股票repr。

+0

误解了你的问题。发布另一个(希望正确)的答案。 –

回答

18

您需要在元类上定义__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> 
+0

击败我吧+1。 –

+3

请注意,在Python 3中'__metaclass__'没有特别的含义,相反,您应该使用'class A(metaclass = Meta)'。 –

+0

@RobWouters感谢:)没有意识到已经改变。 –

0

我可以定义一个__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. 
相关问题