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

12 投票
3 回答
17311 浏览
提问于 2025-04-15 20:44

我该如何重写一个类的特殊方法呢?

我想在不创建类的实例的情况下,调用这个类的 __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 内置的定义。只有在用 Foo().__str__() 的时候才有效,而用 Foo.__str__() 就不行。

3 个回答

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?

你真的确定不想调用一个类方法吗?

1

你为什么想要滥用 __str__ 这个方法的意思呢?这个方法名(就像很多特殊方法名一样)在Python中是特别的,它是一个实例方法,意思是“返回这个类的实例的字符串表示”。

如果你想要一个只返回静态字符串的函数,最好把它单独放在一个函数里,而不是放在类里面。

如果你想要一个构造函数返回一个新的字符串,给它起个别的名字,这样就不会和特殊的 __str__ 名字冲突了。

如果你想要一个方法来打印类的表示,最好不要用 __str__ 这个名字。这个名字的含义是——正如双下划线风格的名字所暗示的——在Python文档中有特定的行为。选择一个(非双下划线)名字,这样你可以赋予它特殊的含义,并且别忘了把它定义为类方法。

20

在一个类里定义的特殊方法 __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

撰写回答