Should I ever directly call object.__str__()?

2019-06-28 04:52发布

问题:

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.

回答1:

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)

  1. str(myObj) == myObj.__str__()
  2. format("{}", myObj) == format("{}", myObj.__str__())
  3. 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.



回答2:

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.



回答3:

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.



回答4:

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.



标签: python oop