2012-01-21 31 views
11

Tôi có thể xác định __repr__ cho một lớp học chứ không phải là một cá thể không? Ví dụ, tôi đang cố gắng để làm điều nàyTôi có thể xác định __repr__ cho một lớp chứ không phải là một cá thể không?

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

Những gì tôi nhận được là

In [58]: a=A() 

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

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

Tôi đang cố gắng để có được đầu ra của dòng 60 để trông giống như "Class A của tôi", không cho ví dụ a. Lý do tôi muốn làm điều này là tôi tạo ra rất nhiều lớp bằng cách sử dụng metaclass của Python. Và tôi muốn một cách dễ đọc hơn để xác định lớp học hơn là chứng khoán.

+0

Hiểu sai sự cố của bạn. Đã đăng một câu trả lời khác (hy vọng đúng). –

Trả lời

18

Bạn cần xác định __repr__ trên metaclass.

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

class A(object): 
    __metaclass__ = Meta 

__repr__ trả về đại diện cho một thể hiện của đối tượng. Vì vậy, bằng cách xác định __repr__ trên A, bạn đang chỉ định những gì bạn muốn repr(A()) giống như thế.

Để xác định biểu diễn của lớp, bạn cần phải xác định cách thể hiện một thể hiện của type. Trong trường hợp này, hãy thay thế type bằng metaclass tùy chỉnh với __repr__ được xác định là bạn cần.

>> repr(A) 
My class A 

Nếu bạn muốn xác định tùy chỉnh __repr__ cho mỗi lớp, tôi không chắc chắn có cách nào đặc biệt rõ ràng để làm điều đó. Nhưng bạn có thể làm một cái gì đó như thế này.

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 

Sau đó, bạn có thể tùy chỉnh trên cơ sở mỗi lớp.

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

Đánh tôi với nó, +1. –

+3

Lưu ý rằng trong Python 3 '__metaclass__' không có ý nghĩa đặc biệt, thay vào đó bạn nên sử dụng' lớp A (metaclass = Meta) '. –

+0

@RobWouters Cảm ơn :) Không nhận ra điều đó đã thay đổi. –

0

Tôi có thể xác định một __repr__ cho một lớp học chứ không phải là một ví dụ?

Chắc chắn, tôi chứng minh ở đây, với một __repr__ đã vượt qua bài kiểm tra 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__) 

Và để chứng minh:

class Foo(object): pass 

class Bar(object): pass 

Hoặc Python 2:

class Baz(Foo, Bar): 
    __metaclass__ = Type 

Hoặc Python 3:

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

Hoặc khá phổ biến:

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

Và để làm repr kiểm tra:

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

kiểm tra repr là gì?Bài kiểm tra ở trên từ tài liệu trên 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. 
Các vấn đề liên quan