mirror of
https://github.com/satwikkansal/wtfpython
synced 2024-12-22 12:50:23 +01:00
Translate Schrödinger's variable * example
This commit is contained in:
parent
361ac5f49b
commit
4576463fcc
77
translations/README-ru.md
vendored
77
translations/README-ru.md
vendored
@ -922,3 +922,80 @@ board = [row] * 3
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
|
||||
### ▶ Переменная Шредингера *
|
||||
<!-- Example ID: 4dc42f77-94cb-4eb5-a120-8203d3ed7604 --->
|
||||
|
||||
|
||||
```py
|
||||
funcs = []
|
||||
results = []
|
||||
for x in range(7):
|
||||
def some_func():
|
||||
return x
|
||||
funcs.append(some_func)
|
||||
results.append(some_func()) # обратите внимание на вызов функции
|
||||
|
||||
funcs_results = [func() for func in funcs]
|
||||
```
|
||||
|
||||
**Вывод (Python version):**
|
||||
```py
|
||||
>>> results
|
||||
[0, 1, 2, 3, 4, 5, 6]
|
||||
>>> funcs_results
|
||||
[6, 6, 6, 6, 6, 6, 6]
|
||||
```
|
||||
|
||||
Значения `x` были разными в каждой итерации до добавления `some_func` к `funcs`, но все функции возвращают `6`, когда они исполняются после завершения цикла.
|
||||
|
||||
2.
|
||||
|
||||
```py
|
||||
>>> powers_of_x = [lambda x: x**i for i in range(10)]
|
||||
>>> [f(2) for f in powers_of_x]
|
||||
[512, 512, 512, 512, 512, 512, 512, 512, 512, 512]
|
||||
```
|
||||
|
||||
#### 💡 Объяснение:
|
||||
* При определении функции внутри цикла, которая использует переменную цикла в своем теле, цикл функции привязывается к *переменной*, а не к ее *значению*. Функция ищет `x` в окружающем контексте, а не использует значение `x` на момент создания функции. Таким образом, все функции используют для вычислений последнее значение, присвоенное переменной. Мы можем видеть, что используется `x` из глобального контекста (т.е. *не* локальная переменная):
|
||||
```py
|
||||
>>> import inspect
|
||||
>>> inspect.getclosurevars(funcs[0])
|
||||
ClosureVars(nonlocals={}, globals={'x': 6}, builtins={}, unbound=set())
|
||||
```
|
||||
Так как `x` - глобальная переменная, можно изменить ее значение, которое будет использовано и возвращено из `funcs`
|
||||
|
||||
```py
|
||||
>>> x = 42
|
||||
>>> [func() for func in funcs]
|
||||
[42, 42, 42, 42, 42, 42, 42]
|
||||
```
|
||||
|
||||
* Чтобы получить желаемое поведение, вы можете передать переменную цикла как именованную переменную в функцию. **Почему это работает?** Потому что это определит переменную *внутри* области видимости функции. Она больше не будет обращаться к глобальной области видимости для поиска значения переменной, а создаст локальную переменную, которая будет хранить значение `x` в данный момент времени.
|
||||
|
||||
```py
|
||||
funcs = []
|
||||
for x in range(7):
|
||||
def some_func(x=x):
|
||||
return x
|
||||
funcs.append(some_func)
|
||||
```
|
||||
|
||||
**Вывод:**
|
||||
|
||||
```py
|
||||
>>> funcs_results = [func() for func in funcs]
|
||||
>>> funcs_results
|
||||
[0, 1, 2, 3, 4, 5, 6]
|
||||
```
|
||||
|
||||
`x` больше не используется в глобальной области видимости
|
||||
|
||||
```py
|
||||
>>> inspect.getclosurevars(funcs[0])
|
||||
ClosureVars(nonlocals={}, globals={}, builtins={}, unbound=set())
|
||||
```
|
||||
|
||||
---
|
||||
|
Loading…
x
Reference in New Issue
Block a user