0

Guido van Rossum tweeted:

Python tip: You can use multi-line strings as multi-line comments. Unless used as docstrings, they generate no code! :-)

Does the below multi-line string, when not used as a docstring, take some space in memory?

'''
Hello, folks!
This is a multi-line string.
'''
jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
  • Multi-line strings are ordinary strings. Strings take up memory. – khelwood Mar 06 '21 at 10:33
  • @khelwood This is Guido's tweet: *Python tip: You can use multi-line strings as multi-line comments. Unless used as docstrings, they generate no code! :-)* If they don't generate bytecode, how will they take memory space? This is what I didn't understand. – Sanjay Raut Mar 06 '21 at 10:37
  • @SanjayRaut see my answer, but TLDR: comments (and multi-line comments) do not generate code, they're only in your source file ! – A.D Mar 06 '21 at 10:39
  • @A.D But multi-line comments, in the true sense, don't exist in Python. – Sanjay Raut Mar 06 '21 at 10:41
  • @SanjayRaut They do ;) That syntax you showed is a multi-line comment; it is a docstring only if they are the first thing in a class/function, [etc](https://stackoverflow.com/a/7696966) – A.D Mar 06 '21 at 10:44
  • @A.D I don't think so; I am sure they are *semantically* treated as strings. – Sanjay Raut Mar 06 '21 at 10:47
  • @A.D Try this: ''' Hello\xfolks! This is a multi-line string. ''' — It will throw `SyntaxError`. – Sanjay Raut Mar 06 '21 at 10:51
  • As Kaya's answer points out, assignment is the key; if the string is not assigned to a variable it will not consume memory because it won't be included in the compiled .pyc file – snakecharmerb Mar 06 '21 at 10:55
  • 2
    @snakecharmerb That's not strictly true, for example the code `"bar" + x` doesn't contain an assignment to any variable, but the string `"bar"` appears in the compiled code object. The string has to not be used within another expression or statement at all, an assignment statement is just one possibility. – kaya3 Mar 06 '21 at 10:57
  • @SanjayRaut yes but as far I as I know, not because of the string itself but rather: " (unicode error) 'unicodeescape' codec can't decode bytes in position 4-5: truncated \xXX escape" That said I probably shouldn't try answering python questions when I haven't touched it in such a long time... – A.D Mar 06 '21 at 10:58
  • @SanjayRaut You did not say in your question that you made no use of nor reference to the string in your code. You only said that it was multiline, which does not affect the question of how much memory it takes up. – khelwood Mar 06 '21 at 14:13

1 Answers1

4

It's straightforward to confirm that if you write a string by itself without assigning it to a variable or using it as part of another statement or expression, then that string (1) does not generate any CPython bytecode, and (2) does not appear in the code object's tuple of constants:

>>> code = 'x = 1; "bar"; x = 2;'
>>> from dis import dis
>>> dis(code)
  1           0 LOAD_CONST               0 (1)
              2 STORE_NAME               0 (x)
              4 LOAD_CONST               1 (2)
              6 STORE_NAME               0 (x)
              8 LOAD_CONST               2 (None)
             10 RETURN_VALUE
>>> compile(code, '<string>', 'exec').co_consts
(1, 2, None)

So the string is discarded at compile-time just like a comment would be, and therefore cannot be present in memory at runtime. Note that this applies to all literal values, not just multi-line strings.

kaya3
  • 47,440
  • 4
  • 68
  • 97
  • Well this is what I was trying to say, except it said in a way that actually makes sense, I'll remove my "answer" – A.D Mar 06 '21 at 10:56
  • I can't find a reference to this behaviour in the docs (e.g. https://docs.python.org/3/reference/expressions.html#literals), so I wonder if it's strictly an implementation detail? – jonrsharpe Mar 06 '21 at 11:12
  • @jonrsharpe Everything about CPython bytecode is an implementation detail of CPython - see the [docs](https://docs.python.org/3/library/dis.html) for the `dis` module, second paragraph. The language semantics specified in the official reference shouldn't require that Python be compiled to CPython bytecode at all, and there are conforming implementations of Python which don't, such as PyPy. – kaya3 Mar 06 '21 at 11:20
  • Yes, exactly - my point is that there may be implementations that *don't* optimise out unused literals and therefore *do* generate code (and take up memory, even if only briefly). – jonrsharpe Mar 06 '21 at 11:21
  • Okay, as it's a CPython implementation detail, other implementations like `PyPy` may choose to give that multi-line string memory space, right? I am curious if `PyPy` does that. – Sanjay Raut Mar 06 '21 at 11:24
  • I don't know much about PyPy, I imagine it would have the string in memory only long enough to throw it away (like the CPython compiler does), but maybe that happens at runtime instead of at compile-time. Certainly, Guido's tweet is about CPython, he just wasn't specific about that; since the tweet is from 2011, he probably didn't feel the need to be. The first PyPy release that achieved compliance with the Python language was only a few months before his tweet, and I doubt many people were using PyPy at the time. – kaya3 Mar 06 '21 at 11:29
  • @jonrsharpe Okay, as it's a CPython implementation detail, other implementations like PyPy may choose to give that multi-line string memory space, right? I am curious if PyPy does that. – Sanjay Raut Mar 06 '21 at 11:29