Python重写类(非实例)特殊方法

时间:2010-03-23 05:35:26

标签: python class override

如何覆盖类特殊方法?

我希望能够在不创建实例的情况下调用类的__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__仍然使用__str__的内置Python定义。它仅在Foo().__str__()而不是Foo.__str__()时才有效。

3 个答案:

答案 0 :(得分:19)

在类中定义的特殊方法__str__仅适用于该类的实例,以便为类对象提供不同的行为,您必须在该类的元类中执行此操作,例如(python 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 :(得分:1)

为什么要滥用__str__的含义?该方法名称(如many dunder method names)在Python中是特殊的,是一个实例方法,其含义为“返回此类实例的字符串表示形式”。

如果你想要一个只返回一个静态字符串的函数,最好将它作为一个不在类中的单独函数。

如果您想要一个返回新字符串的构造函数,请将其命名为其他内容,这样就不会破坏特殊的__str__名称。

如果您想要一种打印类表示的方法,则不应使用名称__str__。该名称是 - dunder-style name implies - 预计会particular behaviour as defined in the Python documentation。选择一些你可以赋予你特殊意义的(非dunder)名字,不要忘记把它作为一种课堂方法。

答案 2 :(得分: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?

你绝对确定你不想打电话给班级方法吗?