I'm writing a class in Python and I'm writing a __str__()
function so my print statements can print string representations of instances of that class. Is there ever a reason to directly do something like this:
myObj = Foo(params)
doSomething(myObj.__str__())
It feels like since there are other neater ways to do this, it would be a bad idea (or at least, not proper style) to directly call __str__()
. That said, I can't find a website specifically saying not to.
In general, dunder methods define how an object behaves in a particular context. They aren't intended to be used directly. (The major exception being when you are overriding a dunder method inherited from a parent class.)
In the case of __str__
, there are three documented uses; it is used by the built-in functions str
, format
, and print
so that (roughly speaking)
str(myObj) == myObj.__str__()
format("{}", myObj) == format("{}", myObj.__str__())
print(myObj) == print(myObj.__str__())
.
The key here is that __str__
allows code that isn't built-in to Python to work with these functions; the __str__
method provides the common interface all three can use.
myObj.__str__()
is the same as
str(myObj)
unless someone has the bad idea to hide str
built-in by reassigning its name:
str = lambda x: None
in which case only the first approach would work. But in the general case, it's better to avoid calling those dunder methods directly.
If you want a custom string representation of your class, implement __str__
in your class definition, and then you can call it using str(myObj)
which will call your method. Calling __str__
will be the same, but isn't as clean I'd say.
It is the correct way of representing the object in print statements and logs, but I don't see why you'd ever do
myObj = Foo(params)
doSomething(myObj.__str__())
over
myObj = Foo(params)
doSomething(myObj)
Passing the object as a string to the function seems unnecessary, as it'd be easier to access it's attributes if you passed the object and said function can also call myObj.__str__()
itself.