Область действия и формальные параметры Python являются изменяемыми объектами и функциями замыкания - PullRequest
0 голосов
/ 19 сентября 2019

Это может занять несколько минут, чтобы понять мою проблему, но я надеюсь, что вы можете помочь мне решить ее. Заранее спасибо.

Во-первых, формальным аргументом по умолчанию является список

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 после выполнения?Если да, то как вы интерпретируете функции замыкания?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...