How to check if __str__ is implemented by an object
--
Music by Eric Matyas
https://www.soundimage.org
Track title: Secret Catacombs
--
Chapters
00:00 Question
01:03 Accepted answer (Score 15)
01:38 Answer 2 (Score 1)
02:04 Answer 3 (Score 0)
02:33 Answer 4 (Score 0)
03:21 Thank you
--
Full question
https://stackoverflow.com/questions/1962...
--
Content licensed under CC BY-SA
https://meta.stackexchange.com/help/lice...
--
Tags
#python
#avk47
ACCEPTED ANSWER
Score 17
Since what you want to check is if it has a __str__ implementation that is not the default object.__str__. Therefore, you can do this:
Foo.__str__ is not object.__str__
To check with instantiated objects you need to check on the class:
type(f).__str__ is not object.__str__
This will also work even if Foo doesn't implement __str__ directly, but inherited it from another class than object, which seems to be what you want.
ANSWER 2
Score 1
Any object inheriting from the object base will have a __str__ method, so testing if it exists is negligible.
You could store a flag attribute on the object, and test for that instead:
if not getattr(obj, 'has_str_override_flag'):
override_str_here(obj)
setattr(obj, 'has_str_override_flag', True)
ANSWER 3
Score 0
Well in you object there is __dict__ that contains all the methods and variables that the object has. You can check if a given object has __str__() method implemented by
'__str__' in Employee.__dict__
or
'__str__' in vars(Employee)
There is no difference between vars() and __dict__, just vars() is more Pythonic.
ANSWER 4
Score 0
It turns out that built-in types rely on object.__str__ to do their (smart) formatting. I really only wanted to eliminate useless strings like <__main__.Foo object at 0x10299d390> and still have dict and other types printed properly. My solution:
objre = re.compile(r"<.* object at 0x[0-9a-f]+>")
if objre.fullmatch(str(obj)):
# Do smarter formatting
This won't catch default formatting of modules, functions etc, for which source code could be shown instead via inspect.getsource(), but I am not displaying them in my variable inspector anyway.