|
355 | 355 | " * All length 0 and length 1 strings are interned.\n", |
356 | 356 | " * Strings are interned at compile time (`'wtf'` will be interned but `''.join(['w', 't', 'f'])` will not be interned)\n", |
357 | 357 | " * Strings that are not composed of ASCII letters, digits or underscores, are not interned. This explains why `'wtf!'` was not interned due to `!`. CPython implementation of this rule can be found [here](https://github.com/python/cpython/blob/3.6/Objects/codeobject.c#L19)\n", |
358 | | - " \n", |
| 358 | + "<img src=\"https://raw.githubusercontent.com/satwikkansal/wtfpython/refs/heads/master/images/string-intern/string_interning.svg\" alt=\"Shows a string interning process.\" style=\"display=block; margin:auto\">\n", |
359 | 359 | "+ When `a` and `b` are set to `\"wtf!\"` in the same line, the Python interpreter creates a new object, then references the second variable at the same time. If you do it on separate lines, it doesn't \"know\" that there's already `\"wtf!\"` as an object (because `\"wtf!\"` is not implicitly interned as per the facts mentioned above). It's a compile-time optimization. This optimization doesn't apply to 3.7.x versions of CPython (check this [issue](https://github.com/satwikkansal/wtfpython/issues/100) for more discussion).\n", |
360 | 360 | "+ A compile unit in an interactive environment like IPython consists of a single statement, whereas it consists of the entire module in case of modules. `a, b = \"wtf!\", \"wtf!\"` is single statement, whereas `a = \"wtf!\"; b = \"wtf!\"` are two statements in a single line. This explains why the identities are different in `a = \"wtf!\"; b = \"wtf!\"`, and also explain why they are same when invoked in `some_file.py`\n", |
361 | 361 | "+ The abrupt change in the output of the fourth snippet is due to a [peephole optimization](https://en.wikipedia.org/wiki/Peephole_optimization) technique known as Constant folding. This means the expression `'a'*20` is replaced by `'aaaaaaaaaaaaaaaaaaaa'` during compilation to save a few clock cycles during runtime. Constant folding only occurs for strings having a length of less than 21. (Why? Imagine the size of `.pyc` file generated as a result of the expression `'a'*10**10`). [Here's](https://github.com/python/cpython/blob/3.6/Python/peephole.c#L288) the implementation source for the same.\n", |
|
2947 | 2947 | "\n", |
2948 | 2948 | "When we initialize `row` variable, this visualization explains what happens in the memory\n", |
2949 | 2949 | "\n", |
2950 | | - "<img src=\"https://github.com/satwikkansal/wtfpython/blob/master/images/tic-tac-toe/after_row_initialized.svg\" alt=\"Shows a memory segment after row is initialized..\" style=\"display=block; margin:auto\">\n", |
| 2950 | + "<img src=\"https://raw.githubusercontent.com/satwikkansal/wtfpython/refs/heads/master/images/tic-tac-toe/after_row_initialized.svg\" alt=\"Shows a memory segment after row is initialized.\" style=\"display=block; margin:auto\">\n", |
2951 | 2951 | "\n", |
2952 | 2952 | "And when the `board` is initialized by multiplying the `row`, this is what happens inside the memory (each of the elements `board[0]`, `board[1]` and `board[2]` is a reference to the same list referred by `row`)\n", |
2953 | 2953 | "\n", |
2954 | | - "<img src=\"https://github.com/satwikkansal/wtfpython/blob/master/images/tic-tac-toe/after_board_initialized.svg\" alt=\"Shows a memory segment after board is initialized..\" style=\"display=block; margin:auto\">\n", |
| 2954 | + "<img src=\"https://raw.githubusercontent.com/satwikkansal/wtfpython/refs/heads/master/images/tic-tac-toe/after_board_initialized.svg\" alt=\"Shows a memory segment after board is initialized.\" style=\"display=block; margin:auto\">\n", |
2955 | 2955 | "\n", |
2956 | 2956 | "We can avoid this scenario here by not using `row` variable to generate `board`. (Asked in [this](https://github.com/satwikkansal/wtfpython/issues/68) issue).\n", |
2957 | 2957 | "\n" |
|
0 commit comments