2012-01-21 12 views
11

インスタンスではなくクラスに対して__repr__を定義できますか?例えば、私は私が何を得るこのインスタンスではなくクラスに対して__repr__を定義できますか?

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

をやろうとしていることはないため、私は「私のクラスA」のように見えるようにライン60の出力を取得しようとしている

In [58]: a=A() 

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

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

ですインスタンスa。私がこれをやりたい理由は、Pythonのメタクラスを使ってたくさんのクラスを生成しているからです。そして私は株価よりクラスを識別するためのより読みやすい方法が必要です。

+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. 
関連する問題