In many cases, this invocation of fun_call() would not match its definition signature and it would generate an exception. When that's the case it's not at all a Python gotcha because it halted and forced you to fix the error.
I like this string catenation behavior and I prefer it, even if it causes some confusion in (IMO rare) cases.
Unless I'm using a string more than once or its meaning is unclear, I always use the literal. In most cases, I find it more legible than having to go look up a constant's definition.
he probably meant not using string literals / ints outside of top-level declarations, so you would instead assign all these parameters to "constants" at top level and then use those constants in function calls, hence avoiding this error.