Как использовать замыкания вместо глобальной переменной?
Правильно ли я изменил код с глобальной переменной на замыкание? Прошу без nonlocal.
## Функция с глобальной переменной
def func_g():
global name
name = 'Владимир'
return name
print(func_g())
print(name)
## Функция с замыканием
def func1():
name2 = 'Владимир'
def func2():
return name2
return func2
var = func1('Владимир')
print(var())
print(var.__closure__)
Ответы (1 шт):
Замыкания можно использовать для "скрытых" переменных, которые доступны через геттер и сеттер, но не напрямую. Код практически как у вас, с одним важным исключением. Значение нужно хранить не прямо в переменной, а внутри переменной-контейнера. Например, внутри списка из одного значения. Дело в том, что присвоить новый объект в переменную из замыкания нельзя. Зато можно вызывать методы объекта из замыкания, в частности изменяющие содержимое объекта.
В примере используется нотация type annotations из python3.12. Для более ранних версий можно просто удалить все аннотации, на функциональность это не влияет.
from typing import Callable as Func
def mk_hidden_var[T](init_val : T = None) -> tuple[Func[[],T],Func[[T], None]]:
"""
Создает скрытую переменную с функциями получения и установки значения.
Аргументы:
init_val (T, опционально): Начальное значение переменной. По умолчанию None.
Возвращает:
tuple[Func[[], T], Func[[T], None]]: Кортеж, содержащий функции получения и установки значения.
- getter() -> T: Функция для получения текущего значения переменной.
- setter(val: T) -> None: Функция для установки нового значения переменной.
"""
container : list[T] = [init_val]
def getter()->T:
return container[0]
def setter(val : T) -> None:
container[0] = val
return getter, setter
name_get, name_set = mk_hidden_var('Vladimir')
print(name_get())
name_set('Boris')
print(name_get())