|
1 | | -<p align="center"><img src="/images/logo.png#gh-light-mode-only" alt=""><img src="/images/logo-dark.png#gh-dark-mode-only" alt=""></p> |
| 1 | +<p align="center"> |
| 2 | + <picture> |
| 3 | + <source media="(prefers-color-scheme: dark)" srcset="/images/logo_dark_theme.svg"> |
| 4 | + <source media="(prefers-color-scheme: light)" srcset="/images/logo.svg"> |
| 5 | + <img alt="Логотип wtfpython" src="/images/logo.svg"> |
| 6 | + </picture> |
| 7 | +</p> |
2 | 8 | <h1 align="center">What the f*ck Python! 😱</h1> |
3 | 9 | <p align="center">Изучение и понимание Python с помощью удивительных примеров поведения.</p> |
4 | 10 |
|
@@ -408,7 +414,13 @@ False |
408 | 414 | - Все строки длиной 0 или 1 символа интернируются. |
409 | 415 | - Строки интернируются во время компиляции (`'wtf'` будет интернирована, но `''.join(['w'', 't', 'f'])` - нет) |
410 | 416 | - Строки, не состоящие из букв ASCII, цифр или знаков подчеркивания, не интернируются. В примере выше `'wtf!'` не интернируется из-за `!`. Реализацию этого правила в CPython можно найти [здесь](https://github.com/python/cpython/blob/3.6/Objects/codeobject.c#L19) |
411 | | -  |
| 417 | +<p align="center"> |
| 418 | + <picture> |
| 419 | + <source media="(prefers-color-scheme: dark)" srcset="/images/string-intern/string_interning_dark_theme.svg"> |
| 420 | + <source media="(prefers-color-scheme: light)" srcset="/images/string-intern/string_interning.svg"> |
| 421 | + <img alt="Процесс интернирования строк." src="/images/string-intern/string_interning.svg"> |
| 422 | + </picture> |
| 423 | +</p> |
412 | 424 | - Когда переменные `a` и `b` принимают значение `"wtf!"` в одной строке, интерпретатор Python создает новый объект, а затем одновременно ссылается на вторую переменную. Если это выполняется в отдельных строках, он не "знает", что уже существует `"wtf!"` как объект (потому что `"wtf!"` не является неявно интернированным в соответствии с фактами, упомянутыми выше). Это оптимизация во время компиляции, не применяется к версиям CPython 3.7.x (более подробное обсуждение смотрите [здесь](https://github.com/satwikkansal/wtfpython/issues/100)). |
413 | 425 | - Единица компиляции в интерактивной среде IPython состоит из одного оператора, тогда как в случае модулей она состоит из всего модуля. `a, b = "wtf!", "wtf!"` - это одно утверждение, тогда как `a = "wtf!"; b = "wtf!"` - это два утверждения в одной строке. Это объясняет, почему тождества различны в `a = "wtf!"; b = "wtf!"`, но одинаковы при вызове в модуле. |
414 | 426 | - Резкое изменение в выводе четвертого фрагмента связано с [peephole optimization](https://en.wikipedia.org/wiki/Peephole_optimization) техникой, известной как складывание констант (англ. Constant folding). Это означает, что выражение `'a'*20` заменяется на `'aaaaaaaaaaaaaaaaaaaa'` во время компиляции, чтобы сэкономить несколько тактов во время выполнения. Складывание констант происходит только для строк длиной менее 21. (Почему? Представьте себе размер файла `.pyc`, созданного в результате выполнения выражения `'a'*10**10`). [Вот](https://github.com/python/cpython/blob/3.6/Python/peephole.c#L288) исходный текст реализации для этого. |
@@ -1038,11 +1050,23 @@ board = [row] * 3 |
1038 | 1050 |
|
1039 | 1051 | Когда мы инициализируем переменную `row`, эта визуализация объясняет, что происходит в памяти |
1040 | 1052 |
|
1041 | | - |
| 1053 | +<p align="center"> |
| 1054 | + <picture> |
| 1055 | + <source media="(prefers-color-scheme: dark)" srcset="/images/tic-tac-toe/after_row_initialized_dark_theme.svg"> |
| 1056 | + <source media="(prefers-color-scheme: light)" srcset="/images/tic-tac-toe/after_row_initialized.svg"> |
| 1057 | + <img alt="Ячейка памяти после того, как переменная row инициализирована." src="/images/tic-tac-toe/after_row_initialized.svg"> |
| 1058 | + </picture> |
| 1059 | +</p> |
1042 | 1060 |
|
1043 | 1061 | А когда переменная `board` инициализируется путем умножения `row`, вот что происходит в памяти (каждый из элементов `board[0]`, `board[1]` и `board[2]` является ссылкой на тот же список, на который ссылается `row`) |
1044 | 1062 |
|
1045 | | - |
| 1063 | +<p align="center"> |
| 1064 | + <picture> |
| 1065 | + <source media="(prefers-color-scheme: dark)" srcset="/images/tic-tac-toe/after_board_initialized_dark_theme.svg"> |
| 1066 | + <source media="(prefers-color-scheme: light)" srcset="/images/tic-tac-toe/after_board_initialized.svg"> |
| 1067 | + <img alt="Ячейка памяти после того, как переменная board инициализирована." src="/images/tic-tac-toe/after_board_initialized.svg"> |
| 1068 | + </picture> |
| 1069 | +</p> |
1046 | 1070 |
|
1047 | 1071 | Мы можем избежать этого сценария, не используя переменную `row` для генерации `board`. (Подробнее в [issue](https://github.com/satwikkansal/wtfpython/issues/68)). |
1048 | 1072 |
|
|
0 commit comments