[Tutor] __str__ vs. sys.displayhook

Albert-Jan Roskam sjeik_appie at hotmail.com
Sun Mar 20 15:57:55 EDT 2016


----------------------------------------
> Date: Mon, 21 Mar 2016 02:50:17 +1100
> From: steve at pearwood.info
> To: tutor at python.org
> Subject: Re: [Tutor] __str__ vs. sys.displayhook
>
> On Sun, Mar 20, 2016 at 01:53:04PM +0000, Albert-Jan Roskam wrote:
>> Hi,
>>
>> The other day I was playing with this to make a convenient string version of a named tuple:
>>
>>>>> from collections import namedtuple as nt
>>>>> Record = nt("Record", "x y z")
>>>>> Record.__str__ = lambda self: "| %s |" % " | ".join([item + ": " + str(getattr(self, item)) for item in self._fields])
>>>>> str(Record(1, 2, 3))
>> '| x: 1 | y: 2 | z: 3 |'
>>
>> Then, after reading another discussion on the main Python list (https://www.mail-archive.com/python-list@python.org/msg409771.html) I realized I could do the same thing with a displayhook.
>> When would I (re)implement __str__, and when would I redefine sys.displayhook? Does the displayhook also affect the way things are logged (with the ' logging'  module)? It feels like sys.displayhook is more " heavy artillery",. but I might be wrong about that.
>
> As the documentation says, "sys.displayhook is called on the result of
> evaluating an expression entered in an interactive Python session." So
> the answer to your question is, you would redefine sys.displayhook when
> you want to control how objects are displayed in the interactive Python
> shell.
>
> https://docs.python.org/3/library/sys.html#sys.displayhook
>
> When you run a script, sys.displayhook is never called. It is only
> called when you are in interactive mode, typing at the Python prompt.


It seems that ipython uses a displayhook in conjunction with pprint.pprint. Or at least something to that effect. That is *very* convenient, esp. with unordered objects like dictionaries.


> When you assign a value to a variable:
>
> the_string = repr(some_expression)
>
> sys.displayhook is never called.
>
> sys.displayhook has nothing to do with the repr or str conversion,
> except in the sense that the display hook will probably *use* the
> value's repr or str. For instance, here's a rather silly display hook in
> action:

aha, so it's an implementation detail of the hook to often use str or repr. But not a requirement.


> py> def hook(value):
> ... if value is None: return
> ... sys.stdout.write("+++REDACTED+++\n")
> ...
> py> sys.displayhook = hook
> py> 23 + 1
> +++REDACTED+++
> py> 1000*2
> +++REDACTED+++
> py> "hello".upper()
> +++REDACTED+++
>
> But even with this display hook in place, the repr and str of values are
> unchanged. It's just tricky to see them unless you bypass the hook:
>
> py> print(23 + 1) # print directly to the screen without calling hook
> 24
>
> You will re-define __str__ when you want to control how objects are
> converted to strings using the str() function, and __repr__ for how
> objects are converted using the repr() function.
>
> The intention is that repr() returns the "string representation" of the
> object ("what does it look like?") while str() "converts this object to
> a string". They are usually the same, but not always:
>
> py> from fractions import Fraction
> py> x = Fraction(1, 2)
> py> print(str(x))
> 1/2
> py> print(repr(x))
> Fraction(1, 2)

That makes sense to me. I read somewhere [1, 2]) that __repr__, when implemented and when possible, should return an eval-able representation of the object (though this is not enforce/checked). Or as somebody put it: __str__ is about readability, and __repr__ is about eval-ability:
eval(repr(obj)) == obj, e.g.

>>> d = {1: 100000}
>>> eval(repr(d)) == d
True

[1] https://docs.python.org/2/reference/datamodel.html#object.__repr__
[2] http://stackoverflow.com/questions/1436703/difference-between-str-and-repr-in-python
 		 	   		  


More information about the Tutor mailing list