Это может занять несколько минут, чтобы понять мою проблему, но я надеюсь, что вы можете помочь мне решить ее. Заранее спасибо.
Во-первых, формальным аргументом по умолчанию является список
def test(x: list=[]) -> None:
print(id(x), x, end='\t')
x.append(1)
print(x)
test() # 4756573320 [] [1]
test() # 4756573320 [1] [1, 1]
Во-вторых, формальным аргументом по умолчанию является неизменяемый объект (строка)
a = 'x_!'
b = 'x_!'
a is b, id(a), id(b)
(False, 4613506864, 4612200128)
Тогда как насчет этого?
def test2(y: str='x_!') -> None:
print(id(y), y, end='\t')
y += y
print(id(y), y)
test2()
x = 'x_!'
print(x, id(x))
test2()
test2()
результат:
4513179104 x_!4513181456 x_! X _!
x_!4513179104
4513179104 x_!4513181456 x_! X _!
4513179104 x_!4513181456 x_! X _!
Третий позиционный аргумент?
def test3(x:'position_args') -> None:
print(id(x), x, end='\t')
x.append(6)
print(id(x), x)
test3([])
test3([])
y = [] # must a list
print(y, id(y))
test3([])
reslut:
4750414024 [] 4750414024 [6]
4750414024 [] 4750414024[6]
[] 4750414024
4749427208 [] 4749427208 [6]
Тогда, если аргумент по умолчанию является списком?
def test4(t: list=[]) -> None:
print(t, id(t),end='/')
t.append(6)
print(t, id(t))
test4()
b = [6]
print(b, id(b))
test4()
результат:
[] 4583033992 / [6] 4583033992
[6] 4680932488
[6] 4583033992 / [6, 6] 4583033992
Каксбивает с толку!Это смущает меня на неделю!
Но сферу применения Closure понять сложнее.
x = 4
def outer(x: list=[]):
print(x, id(x))
z = 9
def inner(y: list=[]):
print(x, id(x))
y.append(1)
# print(z)
print("inner", y, id(y))
x.append(6)
return inner
outer()()
res = outer() # Variable to accept
res()
Результаты:
[] 4583033992
[6] 4583033992
внутренний: [1] 4680931976
[6] 4583033992
[6, 6] 4583033992
внутренний: [1] 4680931976
Почему два вызова внешней функции приводят к разным внутренним функциям seems Это, похоже, создает новый список, однако идентификатор нового списка тот же.
Тогда все возвращаемые значения принимаются с переменными.
x = 4
def outer(x: list=[]):
print(x, id(x))
z = 9
def inner(y: list=[]):
print(x, id(x))
y.append(1)
# print(z)
print("inner: ", y, id(y))
x.append(6)
return inner
# Variable to accept
a = outer()
res = outer()
print('ID:', id(a), id(res))
a()
res()
результат:
[] 4671392328
[6] 4671392328
ID: 4673413872 4673413600
[6,6] 4671392328
внутренний: [1] 4680932104
[6, 6] 4671392328
внутренний: [1] 4671390024
Каждый вызов на внешнийФункция возвращает другую функцию, потому что их идентификатор отличается.Интересно то, что у - новый список, но у него другой идентификатор.
Таким образом, можно сказать, что external () () заставляет функцию выполняться и освобождает всю память у, а затем сразудать последующий вызов res () для генерации того же адреса для y, верно?
Кстати, когда я запускаю тесты отладки, функция завершает выполнение, ее локальные объекты исчезают, и если вы запускаете его снова, локальныесловарь интеллектуально генерирует необходимые переменные из внутренних функций.
x = 4
def outer(x: list=[]):
print(x, id(x))
z = 9
def inner(y: list=[]):
print(x, id(x))
y.append(1)
# print(z)
print("inner: ", y, id(y))
x.append(6)
return inner
# Variable to accept
a = outer()
res = outer()
print('ID:', id(a), id(res))
a()
res()
Когда я отлаживаю, если print (z) закомментирует, inner () и z = 9 исчезают внутри словаря locals, и если этослева внутри, inner () появляется внутри словаря местных жителей z = 9, разве это не умно?
Так что большой вопрос в том, скомпилированы ли переменные до их запуска, или они определены во время выполнения?Эта функция освобождает словарь locals после выполнения?Если да, то как вы интерпретируете функции замыкания?