Как поддерживать списки и словари между вызовами функций в Python?

У меня есть функция. Внутри я веду словарь ценностей. Я хочу, чтобы этот словарь поддерживался между вызовами разных функций

Предположим, что dic:

a = {'a':1,'b':2,'c':3}

Скажем, при первом звонке я изменил [a] на 100 Dict становится a = {'a':100,'b':2,'c':3}

На другом звонке я изменил a [b] на 200 Я хочу, чтобы этот диктофон был a = {'a':100,'b':200,'c':3}

Но в моем коде [a] не остается 100. Оно изменяется на начальное значение 1.

Мне нужен ответ как можно скорее .... Я уже опоздала ... Помогите, пожалуйста, друзья ...

Пожалуйста, укажите код, который вы используете. Ваше описание без кода слишком расплывчатое. Пожалуйста, укажите код. Код помогает.

S.Lott 07.01.2009 14:11

Я предполагаю, что вы имеете в виду ['a'], а не [a]. >>> a = {'a': 1, 'b': 2, 'c': 3} >>> a [a] Traceback (последний вызов последним): файл "<stdin>", строка 1, в <module> TypeError: объекты dict не могут быть хешированы >>> a ['a'] 1

Tim Kersten 07.01.2009 15:37
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
4
2
10 790
7

Ответы 7

Вы можете использовать статическая переменная:

def foo(k, v):
  foo.a[k] = v
foo.a = {'a': 1, 'b': 2, 'c': 3}

foo('a', 100)
foo('b', 200)

print foo.a

@ ΤΖΩΤΖΙΟΥ также не являются вызываемыми с сохранением состояния. Я не вижу большой пользы в использовании класса для создания функции с отслеживанием состояния, кроме отделения инициализации от использования.

Aaron Maenpaa 07.01.2009 18:36

Причина, по которой это «классная работа», заключается в том, что вам могут понадобиться две функционально идентичные функции, но с разными данными.

gnud 08.01.2009 00:45

@Peter: экземпляр класса - это привязка данных и кода. Именно то, что просил OQ. Вы, очевидно, имеете право поддержать предложенный вами ответ, но голосование за другие решения, полезные для находятся, показывает, мягко говоря, негибкость.

tzot 08.01.2009 19:13

Если внутри функции создается 'a'. Это выходит за рамки. Просто создайте его вне функции (и до вызова функции). При этом список / хэш не будет удален после выхода программы из функции.

a = {'a':1,'b':2,'c':3}

# call you funciton here

Я пробовал это несколькими разными способами, и все они, кажется, работают :) И, что самое главное, это очень просто!

Miquella 07.01.2009 10:01

@nosklo: Он попросил решение. Без кода мы не знаем, что наш список создается глобально. Он мог бы все это уже заключить в другую функцию или класс.

J.J. 07.01.2009 18:35

Возможно, вы говорите о вызываемом объекте.

class MyFunction( object ):
    def __init__( self ):
        self.rememberThis= dict()
    def __call__( self, arg1, arg2 ):
        # do something
        rememberThis['a'] = arg1
        return someValue

myFunction= MyFunction()

С этого момента используйте myFunction как простую функцию. Вы можете получить доступ к словарю rememberThis с помощью myFunction.rememberThis.

Я отредактировал ваш ответ, потому что MyFunction () не будет вызывать функцию, она создаст экземпляр без видимых побочных эффектов, и это будет сбивать с толку.

tzot 07.01.2009 14:32

-1 для использования класса и магических функций для выполнения чего-то тривиального

too much php 07.01.2009 23:52

Я пытаюсь быть агрессивным, но ваша реализация кажется намного более сложной, чем должна быть ...

too much php 07.01.2009 23:53

Под «волшебными функциями» вы имеете в виду специальные имена методов? (python.org/doc/2.5.2/ref/specialnames.html) Или вы имеете в виду что-то еще?

S.Lott 07.01.2009 23:54

Да, я говорю о __call __ () и использовании настраиваемого объекта для замены стандартного типа «функция».

too much php 08.01.2009 03:27

Вы можете «обмануть», используя поведение Python для аргументов по умолчанию. Аргументы по умолчанию оцениваются только один раз; они повторно используются для каждого вызова функции.

>>> def testFunction(persistent_dict = {'a': 0}):
...     persistent_dict['a'] += 1
...     print persistent_dict['a']
...
>>> testFunction()
1
>>> testFunction()
2

Это не самое элегантное решение; если кто-то вызывает функцию и передает параметр, он переопределит значение по умолчанию, что, вероятно, не то, что вам нужно.

Если вам просто нужен быстрый и грязный способ получить результаты, это сработает. Если вы делаете что-то более сложное, возможно, лучше вынести это в класс, как упомянул С. Лотт.

Обновлено: переименовал словарь, чтобы он не скрывал встроенный dict в соответствии с комментарием ниже.

Это работает (и об этом тоже очень полезно знать), но программист-параноик внутри меня беспокоится, что слишком легко заменить словарь, предоставив дополнительный аргумент.

too much php 07.01.2009 23:55

Такого рода практика просто требует, чтобы неясные ошибки проникли в вашу программу.

Algorias 08.01.2009 02:11

@Peter - это может быть особенность. у вас есть один интерфейс для изменения состояния, а также его сброса. зависит от целей кода ...

Daniel Naab 09.01.2009 00:15

Вместо того, чтобы навязывать глобальные переменные в базе кода (это может быть решением вызывающей стороны), я предпочитаю сохранять состояние, связанное с экземпляром функции. Класс хорош для этого, но плохо передает то, что вы пытаетесь выполнить, и может быть немного многословным. На мой взгляд, использование закрытий намного чище.

def function_the_world_sees():
    a = {'a':1,'b':2,'c':3}

    def actual_function(arg0, arg1):
        a[arg0] = arg1
        return a

    return actual_function
stateful_function = function_the_world_sees()

stateful_function("b", 100)    
stateful_function("b", 200)

Главное предостережение, которое следует иметь в виду, заключается в том, что когда вы делаете присваивания в «actual_function», они происходят в «actual_function». Это означает, что вы не можете переназначить a другой переменной. Обход, который я использую, заключается в том, чтобы поместить все свои переменные, которые я планирую переназначить, либо в отдельный список элементов для каждой переменной, либо в словарь.

На мой взгляд, на этот вопрос нет элегантного ответа. Возможные варианты - это вызываемые объекты, значения по умолчанию и взлом атрибутов. Вызываемые объекты - правильный ответ, но они привносят много структуры для того, что было бы одним «статическим» объявлением на другом языке. Значения по умолчанию - это незначительное изменение кода, но оно непонятно и может сбить с толку нового программиста на Python, смотрящего на ваш код. Мне они не нравятся, потому что их существование не скрыто от тех, кто может взглянуть на ваш API.

Я обычно использую хак атрибутов. Мой предпочтительный метод:

def myfunct():
    if not hasattr(myfunct, 'state'): myfunct.state = list()
    # access myfunct.state in the body however you want

Это сохраняет объявление состояния в первой строке функции, которой оно принадлежит, а также сохраняет myfunct как функцию. Обратной стороной является то, что вы выполняете проверку атрибутов каждый раз, когда вызываете функцию. Это почти наверняка не будет узким местом для большей части кода.

Я утверждаю, что значения по умолчанию, как правило, присутствуют и на других языках. Однако идея добавления атрибута к функции может сбить с толку нового программиста на Python, который смотрит на ваш код.

Bobort 29.11.2018 20:23

Лично мне нравится идея глобального заявления. Он не вводит глобальную переменную, но утверждает, что локальный идентификатор фактически относится к идентификатору в глобальном пространстве имен.

d = dict()
l = list()
def foo(bar, baz):
    global d
    global l
    l.append(bar, baz)
    d[bar] = baz

В python 3.0 также есть «нелокальный» оператор.

Другие вопросы по теме