Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python overriding class (not instance) special methods

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

like image 437
André Avatar asked Mar 23 '10 05:03

André


People also ask

Can you override a class method in Python?

Overriding a method in the same class is not allowed. So, you need to do that in the child class by implementing the Inheritance concept. If you want to override the Parent Class method, create a function in the Child with the same name and number of parameters. This is called function overriding in Python.

What does __ call __ do in Python?

The __call__ method enables Python programmers to write classes where the instances behave like functions and can be called like a function. When the instance is called as a function; if this method is defined, x(arg1, arg2, ...) is a shorthand for x. __call__(arg1, arg2, ...) .

Can we override private method in Python?

You can do it still, by naming your object just so: def _Foo__method(self):

What is __ get __ in Python?

Python __get__ Magic Method. Python's __get__() magic method defines the dynamic return value when accessing a specific instance and class attribute. It is defined in the attribute's class and not in the class holding the attribute (= the owner class).


2 Answers

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
like image 53
Anurag Uniyal Avatar answered Oct 08 '22 09:10

Anurag Uniyal


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.

like image 34
bignose Avatar answered Oct 08 '22 11:10

bignose