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

发布于 2024-08-26 08:24:56 字数 977 浏览 9 评论 0原文

如何重写类特殊方法?

我希望能够在不创建实例的情况下调用该类的 __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__() 时才有效。

How do I override a class special method?

I want to be able to call the __str__() method of the class without creating an instance. Example:

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())

produces:

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

should be:

Bar
Bar
StaticBar
StaticBar
ClassBar
ClassBar

Even if I use the @staticmethod or @classmethod the __str__ is still using the built-in Python definition for __str__. It's only working when it's Foo().__str__() instead of Foo.__str__().

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

往事随风而去 2024-09-02 08:24:56

类中定义的特殊方法 __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

Special method __str__ defined in a class works only for the instances of that class, to have the different behavior for class objects you will have to do it in a metaclass of that class e.g. (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()

output:

Klass
instance
初见 2024-09-02 08:24:56

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

如果您想要一个仅返回静态字符串的函数,最好将其作为一个单独的函数而不是在类中。

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

如果您想要一个打印类表示的方法,则不应使用名称 __str__ 。这个名字就是——正如 dunder 风格的名字所暗示的 – 预计具有Python 文档中定义的特定行为。选择一些可以赋予特殊含义的(非dunder)名称,并且不要忘记将其设为类方法。

Why do you want to abuse the meaning of __str__? That method name (like many dunder method names) is special in Python, being an instance method with the meaning "return a string representation of this instance of the class".

If you want a function that just returns a static string, it would be better to have that as a separate function not inside a class.

If you want a constructor that returns a new string, name it something else so it's not clobbering the special __str__ name.

If you want a method for printing a representation of the class, you should not use the name __str__ for that. That name is – as the dunder-style name implies – expected to have particular behaviour as defined in the Python documentation. Choose some (non-dunder) name which you can give your special meaning, and don't forget to make it a class method.

初吻给了烟 2024-09-02 08:24:56

我不确定你到底想做什么。让我添加一些随机信息。

首先,添加这个类:

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?

你绝对确定你不想调用类方法吗?

I'm not sure what you are trying to do, exactly. Let me just add a bit of random information.

First, add this class:

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

Print this instead:

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?")

To get 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?

Are you absolutely sure you don't want to call a classmethod?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文