4

It would be useful for mo to include a comment in an f-string. For instance, take this code:

f"""
<a
   href="{ escape(url) }"
   target="_blank" { # users expect link to open in new tab }
>bla</a>
"""

It would be nice if this code was equivalent to:

f"""
<a
   href="{ escape(url) }"
   target="_blank" 
>bla</a>
"""

You can include full Python expressions in between the curly brackets, but it looks like you can't include comments. Am I correct? Is there a way to do this?

Flimm
  • 136,138
  • 45
  • 251
  • 267
  • What you can do instead is this: `>>> x=1;y=2 >>> data="""x: {x}, y: not wanted""" >>> data 'x: {x}, y: not wanted' >>> data.format(**locals()) 'x: 1, y: not wanted' >>> data.format(**globals()) 'x: 1, y: not wanted' ` While ugly, it doesn't throw an exception and kind of preserves f-string behavior. However use Jinja or something sane instead of misusing f-strings. – Peter Badida May 23 '20 at 13:15
  • Are you constructing the `html` string yourself or getting it from somewhere else? It's unclear to me what you're doing. – Pedro Lobito May 23 '20 at 17:56
  • @CONvid19 I used the example of HTML because I thought it would be simpler. In reality, I'm actually building an SQL query. – Flimm May 23 '20 at 17:57
  • With your rep, I'd expect you to know how to [ask a good question](https://stackoverflow.com/help/how-to-ask), specifically, describe exactly what you're trying to do, which is clearly not the case when you use an `html` example while trying building an `SQL` query. – Pedro Lobito May 23 '20 at 18:06
  • 2
    @CONvid19 I can't tell you how frustrating it is to look for answers for a question X, find the exact question on SO, only to find that commentators demanded extra details, making the question much more narrow, so that they could answer the Y problem, rather than the question X, and so I have to keep looking for the answer to the question X. I know what the XY problem is, but not every question X actually needs an answer to Y, most of the time, I actually need the answer to the question that I asked! – Flimm May 23 '20 at 20:35
  • Sorry to rant, but you've accidentally touched a sore point with my experience of SO. – Flimm May 23 '20 at 20:36

4 Answers4

7

From PEP498:

Comments, using the '#' character, are not allowed inside an expression.

There is no way to comment other than putting a '#' character in Python, so it is not possible.

Asocia
  • 5,935
  • 2
  • 21
  • 46
  • ***There is no way to comment other than putting a '#'***, not true, try `""" some comment """` – Pedro Lobito May 23 '20 at 17:36
  • 2
    @CONvid19 I think you are talking about docstrings. They don't have to be surrounded with triple quotes. They are not comments, and they wouldn't work in this situation. – Flimm May 23 '20 at 17:57
  • They are technically not comments, but they are used as so, namely, multi-line comments. [Is there a way to create multiline comments in Python?](https://stackoverflow.com/questions/7696924/is-there-a-way-to-create-multiline-comments-in-python) – Pedro Lobito May 23 '20 at 17:59
  • 1
    @CONvid19 You can index a tuple with boolean and use it like a ternary operator but does that make it *really* ternary operator? No. It's same thing. You can use some triple quoted string in your code, and expect from your readers to interpret them like comments but for Python they are *still* strings: `>>> 5 + 5 """ is this a comment? """` Nope, `SyntaxError` it is. – Asocia May 23 '20 at 20:39
2

You cannot write a comment inside an expression. But you can write a string in multiple fragments and write a comment between 2 fragments provided the next fragment starts on a different line:

s = (f"""
<a
   href="{ escape(url) }"
   target="_blank" """ # users expect link to open in new tab
f""">bla</a>
""")
Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252
1

No. There is no comment in f-string.

When building a str, template engines may be overkill. Joining a list of str may be desirable.

s = ''.join([
    '<a',
    f' href="{escape(url)}"',
    ' target="_blank">',
    # users expect link to open in new tab
    'bla</a>',
])
Aaron
  • 1,255
  • 1
  • 9
  • 12
  • Unmaintainable in the long run if multiple people edit the same codebase and e.g. skip commas, forget quotes. Unfortunately this is a recipe for disaster if a test suite won't catch it before deployment. – Peter Badida May 23 '20 at 13:37
1

Since the question specifically asked about Python comments in f-strings, Asocia's answer is technically correct; You cannot include Python comments between curly brackets in f-strings.

However, if you are willing to abuse other Python features to emulate comments, then there are other ways to incorporate text into an f-string in source code such that it will not be included in the output of the f-string at run time.

For example:

f"""
<a
   href="{ escape(url) }"
   target="_blank"{ '# users expect link to open in new tab' :.0 }
>bla</a>
"""

Some options:

  • { 'my comment' :.0 } This works by putting the comment in a single-quoted Python string, then using a "format specifier" in the f-string expression to truncate this string to zero length. (":" is a special separator character in f-string expressions, and everything after it is interpreted as a format specifier. The ".0" format specifier sets a "precision" of zero which truncates the string to zero length.)
  • { '# my comment' :.0 } This is the same as the above option, but adding "#" at the beginning of the string may help make it more obvious that this is intended to be a comment.
  • { 'my comment' [:0] } This uses a Python "slice" to return a zero-length substring of the Python string, instead of using a "format specifier" to truncate the string.
  • { 'my comment' and '' } This works by using the and boolean expression to evaluate the first string then (since any non-empty string is evaluated as true) return the second (empty) string.
  • { 'my comment' if False else '' } This works by using a conditional expression (sometimes called a "ternary operator") to ignore the first string and return the second (empty) string.
  • { comment('my comment') } If you are worried about other developers not understanding how the above expressions work or not recognizing that they are intended to be comments, then this may be more explicit. This requires a comment function to be defined separately as shown below.

Example comment function definition:

def comment(_):
  return ''
Paul Donohue
  • 1,121
  • 9
  • 9