mirror of
https://github.com/satwikkansal/wtfpython
synced 2024-11-22 11:04:25 +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…
Reference in New Issue
Block a user