Python inline conditional in string concatenation

11.2k Views Asked by At

I had this:

msg = time + b' - ' + Logger.LEVELS_WORD[msg_loglevel] + b': ' + msg.encode('utf-8') + b'\n'

Since sometimes msg was already bytes, I wanted to concat msg.encode('utf-8') if it was string or else just msg, so I did this:

msg = time + b' - ' + Logger.LEVELS_WORD[msg_loglevel] + b': ' + msg if isinstance(msg, bytes) else msg.encode('utf-8') + b'\n'

But it is not working as I expected, since now msg equals msg. (time + log level isn't getting added).

Should I do if/else instead?

1

There are 1 best solutions below

0
On BEST ANSWER

A conditional expression has a very low precedence; it is executed last only before a lambda. As such the expression, as written, choses between either time + b' - ' + Logger.LEVELS_WORD[msg_loglevel] + b': ' + msg or msg.encode('utf-8')) + b'\n'.

Put the conditional expression with the if and else branches in parentheses:

msg = time + b' - ' + Logger.LEVELS_WORD[msg_loglevel] + b': ' + (
    msg if isinstance(msg, bytes) else msg.encode('utf-8')) + b'\n'

Consider using duck-typing (test for hasattr(msg, 'encode')), and breaking up the expression into multiple lines for readability. If you are using Python 3.5 or newer, perhaps you want to use printf-style formatting:

if hasattr(msg, 'encode'):
    msg = msg.encode('utf-8')
msg = b'%s - %s: %s\n' % (time, Logger.LEVELS_WORD[msg_loglevel], msg)