Время жизни (объем памяти) локальных переменных внутри функции
def some_function():
some_dict = {'random': 'values'}
a = some_dict['random']
return a
Когда словарь some_dict
создается в памяти? (в первый раз функция вызывается?)
Когда словарь some_dict
уничтожен/удален? (когда функция вернется?)
Если это так, означает ли это, что объект словаря будет создаваться при каждом вызове функции?
Стоит ли беспокоиться о таких вещах при изучении/работе с питоном?
- Как лучше всего справляться с такими ситуациями? Лучше ли создавать словарь глобально, чтобы избежать создания и уничтожения словаря при каждом вызове функции?
Где я могу узнать о таких деталях языка? Я попытался просмотреть документы, но не смог найти то, что искал.
Буду признателен, если вы ответите на все 4 вопроса!
Ответы
Ответ 1
- Словарь
some_dict
будет создан в памяти каждый раз, когда вызывается функция.
- Он освобождается при возврате функции.
- Очень дорого воссоздать словарь каждый раз, когда вызывается функция, особенно если словарь большой. Вместо этого вы можете создать словарь в функции вызывающего абонента (при условии, что сам вызывающий вызов вызывается только один раз) и передать его в качестве аргумента функции
some_function()
.
Например, рассмотрим функцию caller()
, которая вызывает в вашем вопросе функцию callee
(some_function()
), как в
def caller():
callee()
Из вашего случая использования мы хотим вызвать callee()
несколько раз, и нам нужно повторно использовать тот же словарь в callee()
. Пусть пробегают обычные случаи использования.
1. Словарь генерируется в callee()
. Это пример вашего вопроса.
def caller():
for loop:
callee()
def callee(dictionary):
generate dictionary
do something with dictionary
В этом случае вызывается каждый раз callee()
, вам нужно создать новый словарь. Это происходит потому, что как только callee()
возвращается, все локальные переменные освобождаются. Поэтому вы не можете "повторно использовать" один и тот же словарь между разными callee()
s.
2. Словарь генерируется в caller()
и передается как аргумент callee()
.
def caller():
generate dictionary
for loop:
callee(dictionary)
def callee(dictionary):
do something with dictionary
В этом случае вы создаете словарь один раз в caller()
, а затем передаете его каждой функции callee()
. Поэтому каждый раз, когда вы вызываете callee()
, вам не нужно будет восстанавливать словарь.
Словарь передается по ссылке, поэтому вы не передаете огромную структуру данных при каждом вызове callee()
. Я не собираюсь углубленно рассказывать об этом (вы можете найти хорошее объяснение здесь), но по сути, есть незначительная стоимость, чтобы передать словарь в качестве параметра до callee()
.
Ответ 2
Когда словарь some_dict уничтожен/отменен? (когда функция возвращает?)
Прежде всего, локальные переменные уничтожаются, как только вы удаляетесь от этой области.
Например, в вашей функции при возврате вы теряете все ссылки на переменные, определенные как some_dict
. Поскольку вы возвращаете a
, и если у вас нет чего-то типа a_var = some_function()
, где ссылка a
будет найдена в a_var
, вы также потеряете a
.
Когда в памяти создается словарь some_dict? (первый раз функция вызывается?)
some_dict = {'random': 'values'} # здесь для каждого вызова метода.
Должен ли я беспокоиться о таких вещах при изучении/работе с python?
да, проверьте приведенный ниже пример
>>> dictionary = {1: 1, 2: 2}
>>> function()
>>> def function():
dictionary = {1: 2, 2:1}
print dictionary
>>> function()
{1: 2, 2: 1}
>>> dictionary
{1: 1, 2: 2}
здесь вы могли предположить, что вы переписываете словарь, но python создает локальный словарь и теряется вскоре после возврата из функции
как все вышло выше, используйте global, он скажет, что вы пытаетесь ссылаться на объект define вне функции.
>>> def function():
global dictionary
dictionary = {1: 2, 2:1}
print dictionary
>>> function()
{1: 2, 2: 1}
>>> dictionary
{1: 2, 2: 1}
Где я узнаю о таких деталях языка? Я пробовал смотреть в документы, но не смогли найти то, что я искал.
Вероятно, вопрос должен быть how do I learn such details
, прост с практикой и понимать документацию и читать снова.