Search code examples
pythonconditional-expressions

Python inline conditional in string concatenation


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?


Solution

  • 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)