Python overriding class (not instance) special methods
Solution 1
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
Solution 2
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.
André
Updated on June 24, 2022Comments
-
André almost 2 years
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'sFoo().__str__()
instead ofFoo.__str__()
.-
user1066101 about 14 years-1: "call the
__str__()
method of the class without creating an instance". Breaks every understanding anyone has of what an object is. Please do not do this. It makes the program absolutely violate our most fundamental expectations. -
Dan Homerick almost 14 yearsI disagree. If you call str(MyClass) then there's no reason you would expect it to behave as though you just called str(myClassObject). That is, there are no fundamental expectations to begin with. I suspect he wants to create a static class and never intends to create any instances of it.
-
-
André about 14 yearsI had to use the new py3 syntax of class C(metaclass=M): ... but it works!
-
timgeb about 6 years"That method is reserved for the meaning "return a string representation of this instance"" <- the class is an instance itself, namely of
type
, so there's no conceptual problem with wanting to have a nice printout for a class.class A(object): pass; isinstance(A, type)
->True
. -
bignose about 6 years@timgeb: I've updated the answer to account for that, thanks.