3

First off all, sorry: I'm quite certain this might be a "duplicate" but I didn't succeed finding the right solution.

I simply want to replace all linebreaks within my sql-code for logging it to one line, but Python's f-string doesn't support backslashes, so:

# Works fine (but is useless ;))
self.logger.debug(f"Executing: {sql.replace( 'C','XXX')}")

# Results in SyntaxError: 
# f-string expression part cannot include a backslash
self.logger.debug(f"Executing: {sql.replace( '\n',' ')}")

Of course there are several ways to accomplish that before the f-string, but I'd really like to keep my "log the line"-code in one line and without additional helper variables.

(Besides I think it's a quite stupid behavior: Either you can execute code within the curly brackets or you cant't...not "you can, but only without backslashes"...)

This one isn't a desired solution because of additional variables:

How to use newline '\n' in f-string to format output in Python 3.6?

General Update The suggestion in mkrieger1s comment:

        self.logger.debug("Executing %s", sql.replace('\n',' '))

Works fine for me, but as it doesn't use f-strings at all (beeing that itself good or bad ;)), I think I can leave this question open.

evilive
  • 916
  • 1
  • 7
  • 24
  • 4
    You don’t need an f-string here. Just use `logger.debug("Executing %s", sql.replace(...))` for the additional benefit of not doing the string interpolation when it's actually logged. – mkrieger1 May 18 '19 at 12:16
  • 1
    @mkrieger1 #1) Your suggestions works fine for me, thank you! Until now I just really preferred f-strings #2) The Question/Answers you found didn't, I read that one before... – evilive May 18 '19 at 12:21
  • This comment solves your problem without helper variable: https://stackoverflow.com/questions/44780357/how-to-use-newline-n-in-f-string-to-format-output-in-python-3-6#comment76542691_44780357 – sanyassh May 18 '19 at 12:31
  • @Sanyash: It uses an additional variable for the newline...so it works, but it is not the solution i want :) – evilive May 18 '19 at 13:00
  • It doesn't use additional variable. It uses `chr(10)` without declaring a variable on separate line. Do you feel the difference? – sanyassh May 18 '19 at 13:01

3 Answers3

4

I found possible solutions

from os import linesep

print(f'{string_with_multiple_lines.replace(linesep, " ")}')

Best,

Joel Zamboni
  • 160
  • 1
  • 6
  • Thank you, used that in the meantime already, seems to be the most correct (and plattform independant) way for me, – evilive Oct 14 '21 at 10:14
1

You can do this

newline = '\n'
self.logger.debug(f"Executing: {sql.replace( newline,' ')}")
Nithin
  • 1,065
  • 8
  • 15
-1
  1. don't use f-strings, especially for logging
  2. assign the newline to a constant and use that, which you apparently don't want to
  3. use an other version of expressing a newline, chr(10) for instance

(Besides I think it's a quite stupid behavior: Either you can execute code within the curly brackets or you cant't...not "you can, but only without backslashes"...)

Feel free to take a shot at fixing it, I'm pretty sure this restriction was not added because the PEP authors and feature developers wanted it to be a pain in the ass.

Masklinn
  • 34,759
  • 3
  • 38
  • 57
  • 5
    Why wouldn't you use "f strings" (formatted strings) when logging? And why do you need to assign `\n` as a constant? there's no speed improvement or readability improvement? – Torxed May 18 '19 at 12:16
  • Same reason why you wouldn't use % or .format for logging: because that makes the formatting eager and means the logging-processing pipeline can't work on the various items, which it may want to. – Masklinn May 18 '19 at 12:17
  • Could you explain #1 (don't use it) a little? – evilive May 18 '19 at 12:17
  • Use use one of the previous methods of formatting strings: logging has its own (based on printf patterns), just `logging.debug(format_string, *args)` and it'll do the formatting internally, alternatively outside of logging contexts use % or .format. – Masklinn May 18 '19 at 12:18
  • @evilive see https://stackoverflow.com/questions/4148790/lazy-logger-message-string-evaluation – mkrieger1 May 18 '19 at 12:19
  • @Masklinn Not sure I follow, and this might be because I've never stumbled upon the problem. But `.format()` would only in-line replace `{var}` for `var` before sending it to the logger. in this case, `sql` will be in-line injected and then passed to the logger. The logger can then work on the expanded string, where's the issue? Passing `*args` to the formatter would be equal to `f'{sql}'` in this case? – Torxed May 18 '19 at 12:19
  • That it can only work on the string post-formatting, meaning you can't build up on the pre-formatting string (e.g. to classify logging messages or deduplicate when sending messages across the network) because logging never sees it. And if logging is disabled, it also incurs the formatting costs which would otherwise be skipped, and which can sometimes be significant. – Masklinn May 18 '19 at 12:21
  • @Torxed re: assign newline to constant - because that circumvents not being able to use a backslash in an f-string. – mkrieger1 May 18 '19 at 12:21