How to check if __str__ is implemented by an object

I want to dynamically implement the __str__ method on an object if the object has not yet implemented it.

I try to use hasattr(obj, '__str__') , it always returns true to me, as it takes it from the class of the object.

Is there a way to determine if an object really implements __str__ ?

I know I can use inspect.getmembers(obj) , but I'm looking for a more pythonic way

EDIT

 class Employee(object): def __init__(self, name, age, emp_code): self.name = name self.age = age self.emp_code = emp_code 

Test

 e = Employee("A", 23, "E1") print hasattr(e, '__str__') >> True 

I want a check that returns False instead of choosing a method inherited from object .

+10
python
source share
5 answers

Since you want to check if it has an __str__ implementation, which is not the default value of object.__str__ . So you can do this:

 Foo.__str__ is not object.__str__ 

To check using object instances, you need to check the class:

 type(f).__str__ is not object.__str__ 

This will also work, even if Foo does not directly implement __str__ , but inherits it from a class other than object , which you seem to need.

+11
source share

Any object that inherits from the object base will have a __str__ method, so testing if it exists is void.

You can save the flag attribute on the object and check instead:

 if not getattr(obj, 'has_str_override_flag'): override_str_here(obj) setattr(obj, 'has_str_override_flag', True) 
0
source share

Your object has __dict__, which contains all the methods and variables that the object has. You can check if this object has a __str __ () method implemented

 '__str__' in Employee.__dict__ 

or

 '__str__' in vars(Employee) 

There is no difference between vars () and __dict__, just vars () is more Pythonic.

0
source share

It turns out that built-in types rely on object.__str__ for their (smart) formatting. I really only wanted to exclude useless strings such as <__main__.Foo object at 0x10299d390> , and still print dict and other types correctly. My decision:

 objre = re.compile(r"<.* object at 0x[0-9a-f]+>") if objre.fullmatch(str(obj)): # Do smarter formatting 

This will not reflect the formatting of modules, functions, etc. by default, for which instead one could show the source code via inspect.getsource() , but I still don't display them in my variable inspector.

0
source share

Use type (e) .__ dict __. Get (method_name) to avoid KeyError if method_name does not exist in the class when using type (e) .__ dict __ [method_name]

 e = Employee("A", 23, "E1") if type(e).__dict__.get('__str__'): print('__str__ implemented') else: print('__str__ not implemented') 
0
source share

All Articles