2010-03-23 30 views
9

如何重寫類特殊方法?Python重寫類(不是實例)特殊方法

我希望能夠在不創建實例的情況下調用該類的__str__()方法。例如:

class Foo: 
    def __str__(self): 
     return 'Bar' 

class StaticFoo: 
    @staticmethod 
    def __str__(): 
     return 'StaticBar' 

class ClassFoo: 
    @classmethod 
    def __str__(cls): 
     return 'ClassBar' 

if __name__ == '__main__': 
    print(Foo) 
    print(Foo()) 
    print(StaticFoo) 
    print(StaticFoo()) 
    print(ClassFoo) 
    print(ClassFoo()) 

生產:

<class '__main__.Foo'> 
Bar 
<class '__main__.StaticFoo'> 
StaticBar 
<class '__main__.ClassFoo'> 
ClassBar 

應該是:

Bar 
Bar 
StaticBar 
StaticBar 
ClassBar 
ClassBar 

即使我使用@staticmethod@classmethod__str__依然採用內置Python定義__str__。它僅在Foo().__str__()而不是Foo.__str__()時有效。

+0

-1:「調用類的__str __()'方法而不創建實例」。打破每個人對任何事物的理解。請不要這樣做。它使程序絕對違反了我們最基本的期望。 – 2010-03-23 10:18:30

+5

我不同意。如果你調用str(MyClass),那麼你沒有理由期望它像你剛剛調用str(myClassObject)那樣行事。也就是說,從一開始就沒有基本的期望。我懷疑他想創建一個靜態類,並且從不打算創建它的任何實例。 – 2010-07-29 23:33:50

回答

17

在類中定義的特殊方法__str__僅適用於該類的實例,爲了使類對象具有不同的行爲,您必須在該類的元類中執行此操作,例如, (蟒蛇2.5)

class Meta(type): 
    def __str__(self): 
     return "Klass" 

class A(object): 
    __metaclass__ = Meta 

    def __str__(self): 
     return "instance" 

print A 
print A() 

輸出:

Klass 
instance 
+1

我不得不使用新的Py3語法 C類(元類= M): ... 但它的工作原理! – 2010-03-23 06:02:46

1

你爲什麼要濫用__str__的含義?該方法保留爲「返回此實例的字符串表示形式」的含義。

如果你想要一個只返回一個靜態字符串的函數,最好把它作爲一個單獨的函數而不是在一個類中。

如果你想要一個返回一個新字符串的構造函數,把它命名爲別的,所以它不會打破保留的__str__名稱。

0

我不知道你正在嘗試做的,完全是。讓我添加一些隨機信息。

首先,添加這個類:

class FooNew(object): 
def __str__(self): 
    return 'Fubar' 

打印此相反:

if __name__ == '__main__': 
    print "You are calling type for an old style class" 
    print(Foo) 
    print(type.__str__(Foo)) 
    print(Foo()) 
    print("But my Python 2.6 didn't match your output for print(Foo)") 
    print("You are calling object.str() for a new style class") 
    print(FooNew) 
    print(object.__str__(FooNew)) 
    print(FooNew()) 
    print("Why do you want to change this?") 

爲了得到這個:

You are calling type for an old style class 
__main__.Foo 
<class __main__.Foo at 0xb73c9f5c> 
Bar 
But my Python 2.6 didn't match your output for print(Foo) 
You are calling object.str() for a new style class 
<class '__main__.FooNew'> 
<class '__main__.FooNew'> 
Fubar 
Why do you want to change this? 

你絕對相信你不想打電話一個classmethod?