2011-08-18 50 views
6

我瞭解如何提供對象的實例的非正式表示,但我有興趣提供Class的非正式字符串表示形式名稱。如何提供python類的非正式字符串表示形式(非實例)

特別是,我想覆蓋當我打印類(__main __。SomeClass)時返回的內容。

>>> class SomeClass: 
... def __str__(self): 
...  return 'I am a SomeClass instance.' 
... 
>>> SomeClass 
<class __main__.SomeClass at 0x2ba2f0fd3b30> 
>>> print SomeClass 
__main__.SomeClass 
>>> 
>>> x = SomeClass() 
>>> x 
<__main__.SomeClass instance at 0x2ba2f0ff3f38> 
>>> print x 
I am a SomeClass instance. 

回答

8

你的問題叫做元類混淆。在A類中,如果A.__str__(self)是A實例方法的模板,我如何爲A自身提供__str__()方法?元類救援。

下面的鏈接可以比我在這裏更好地解釋這一點。

http://gnosis.cx/publish/programming/metaclass_1.html

http://gnosis.cx/publish/programming/metaclass_2.html

簡單例子在這裏:

class AMeta(type): 
    def __str__(self): 
     return "I am the truly remarkable class A" 

class A(object): 
    __metaclass__ = AMeta 
    def __str__(self): 
     return "I am an A instance" 

print A 
I am the truly remarkable class A 
print A() 
I am an A instance 

順便說一句,你可以爲__repr__這樣做。

+0

已編輯,增加了一個例子。 –

+0

優秀的文檔和示例,謝謝! – adam

+0

我想你的意思是'def __str __(self):'在'class A'中而不是'def str(self):' –

1

改爲取代__repr__

>>> class SomeClass(object): 
... def __repr__(self): 
...  return 'I am a SomeClass instance.' 
+0

不,這覆蓋了實例表示。 –

+0

'__repr__'也適用於實例。它不會做他所說的,我嘗試用@classmethod裝飾'__repr__',但沒有工作:)。 – utdemir

+0

你的代碼仍然不起作用,因爲對於repr(SomeClass)有用,你的'SomeClass .__ repr__'不能有自變量。 –

2

要更改類的字符串表示:

class MC(type): 
    def __repr__(cls): 
     return 'I am Test' 

class Test: 
    __metaclass__ = MC 
    pass 

print Test 

工作正常。

如果您在定義__str__時調用了repr(Test),它將不會使用您的自定義消息。

但是,如果你定義__repr__像我一樣,和str(Test)被調用,它使用custimized消息,因爲__repr__是後備和__str__type定義。

如果你想要做的是改變它的名字:

def renamer(name): 
    def wrapper(func): 
     func.__name__ = name 
     return func 
    return wrapper 

@renamer('Not Test') 
class Test: pass 
print Test.__name__ 

Test.__name__ = 'Test Again' 
print Test.__name__  

都將工作,改變類的名字。

+0

他想改變班級的印刷方式(如str),而不是名字。 –

+0

看看我的第一個代碼示例,它確實如此。第二個例子是改變名稱的例子。事實上,我的回答是在你之前做的。 – agf

1

你可以通過元類實現。

觀察:

>>> class MyMeta(type): 
...  def __init__(cls, name, bases, dct): 
...    super(MyMeta, cls).__init__(name, bases, dct) 
... 
...  def __repr__(self): 
...    return "MyMeta is Cool: " + self.__name__ 
... 
>>> class FooType(metaclass=MyMeta): 
...  pass 
... 
>>> FooType 
MyMeta is Cool: FooType 
3

你就必須重寫元類__str__方法。我不知道你爲什麼想要這樣做,但是無論如何這都是。

>>> class InformalType(type): 
...  def __str__(self): 
...    return self.__name__ 
... 
>>> class MyFoo(object): 
...  __metaclass__ = InformalType 
...  pass 
... 
>>> MyFoo 
<class '__main__.MyFoo'> 
>>> print MyFoo 
MyFoo 
>>> foo = MyFoo() 
>>> foo 
<__main__.MyFoo object at 0x7fdf9581f910> 
>>> print foo 
<__main__.MyFoo object at 0x7fdf9581f910> 
>>> 
+0

+1比我的版本更乾淨。 – Skurmedel

相關問題