This came up in passing in one of the PEP 572 threads, and I'm curious if folks think it's a good idea or not. When debugging, sometimes you have a somewhat complicated expression that's not working:
# Hmm, is func2() returning the right thing? while (func1() + 2 * func2()) < func3(): ...
It'd be nice to print out what func2() returns, but to do that we have to refactor this code, which might be rather tricky in a case like this. I think if you want to use print() directly here, the simplest way to do that is:
while True: tmp = func2() print(tmp) if not (func1() + 2 * func2()) < func3()): break ...
Obviously this is annoying and error prone – especially for beginners, who are the ones most likely to need to print out lots of stuff to figure out why their code isn't working. (Chris Angelico mentioned that he finds this to be a common problem when teaching beginners.)
There is a better way: if you define a trivial helper like:
# "debug print": prints and then returns its argument def dp(obj): print(repr(obj)) return obj
then the rewritten code becomes:
while (func1() + 2 * dp(func2())) < func3(): ...
Of course, this is trivial -- for me or you. But the leap to first realize that this is a useful thing, and then implement it correctly, is really asking a lot of beginners, who by assumption are struggling to do *anything* with Python syntax. And similarly, putting a package on PyPI is useful (cf. the venerable 'q' package), but still adds a significant barrier to entry: you need to be able to install packages, and you need to add an import. In fact, I can imagine that you might want to teach this trick even before you teach what imports are.
So, would it make sense to include a utility like this in __builtins__?
PEP 553, the breakpoint() builtin, provides some relevant precedent. Looking at it, I see it also emphasized the value of letting IDEs override the debugger, and I can see some similar value here: e.g. fancy REPLs like Spyder or Jupyter could potentially capture the objects passed to dp() and make them available for interactive viewing (imagine if they're like a large dataframe or something).
Points to argue over if people like the general idea:
- The name: p(), dp(), debug(), debugprint(), ...? - __str__ or __repr__? Presumably __repr__ since it's a debugging tool. - Exact semantics: there should probably be some way to add a bit of metadata that gets printed out, for cases like:
while (dp(func1(), "func1") + 2 * dp(func2(), "func2")) < dp(func3(), "func3"): ...
Maybe other tweaks would be useful as well.