Python: могу ли я распаковать аргументы без вызова функции?

У меня есть dict, который я хочу преобразовать в несколько разных объектов. Например:

В настоящее время есть

kwargs = {'this': 7, 'that': 'butterfly'}

И я хочу преобразовать его, возможно, используя что-то похожее на распаковку аргумента функции, но без фактического вызова функции, так что я получаю что-то вроде:

Желанный

**kwargs
print(this) # Will print out `7`
print(that) # Will print out `'butterfly'`

Я знаю, что не могу использовать двойную звезду [**], как я показал. Но могу ли я сделать что-то подобное?


Изменить: больше деталей

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

У меня есть свойство в классе, которое я хочу установить с помощью аргументов ключевого слова. Что-то вроде того, что показано здесь, но распаковка kwargs вместо args.

В качестве примера действующей игрушки это выглядит так:


class A(object):
    def __init__(self):
        self._idx = None
    @property
    def idx(self):
        return self._idx
    @idx.setter
    def idx(self, kwargs):
        print(kwargs)
        self._idx = {}
        for kw, val in kwargs.items():
            self._idx[kw] = val

Это работает. Но теперь я выполняю модульное тестирование функции, и в модульном тесте я хотел бы иметь возможность предоставлять определенные пары ключ-значение как обычные объекты, чтобы я мог эффективно использовать hypothesis и pytest @mark.parametrize эффективно.

Для этого, похоже, мне понадобится голая распаковка, как я описал выше.

Поскольку все это на самом деле локальные переменные в методе, я чувствую, что проблемы @ g.d.d.c, вероятно, несущественны. Похоже, его беспокоило то, что я создал новые глобальные переменные, не зная, что они из себя представляют.


person Mike Williamson    schedule 07.10.2020    source источник
comment
Можете ли вы предоставить тест, который вы хотите написать?   -  person Natim    schedule 08.10.2020


Ответы (2)


Примечание: этот подход опасный. Вы не должны (в большинстве случаев) путаться с locals() или globals(). Однако то, что вы хотите, можно сделать, например:

>>> kwargs = {'this': 7, 'that': 'butterfly'}
>>> 
>>> locals().update(kwargs)
>>> this
7
>>> that
'butterfly'

Он по-прежнему вызывает функцию (обновление locals()), но дает вам имена в вашем локальном пространстве имен.

person g.d.d.c    schedule 07.10.2020
comment
Привет @ g.d.d.c, я обновил вопрос, чтобы решить ваши проблемы. Зная, что все действия происходят внутри метода класса, вы все еще чувствуете, что это опасно? Глобальное пространство имен не загромождается. - person Mike Williamson; 07.10.2020

Вы можете сделать:

this, that = {"this": 7, "that": "butterfly"}.values()

Но это действительно специфично. Вопрос в том, почему у вас есть значения в dict в первую очередь.

Кажется, они у вас есть в кваргах, почему вы не можете их там потратить?

Если вы не знаете ключей в словаре, как вы можете использовать их в коде?

Если вы знаете ключи в словаре, почему бы просто не расширить его так:

this, that = kwargs["this"], kwargs["that"]

И мой последний вопрос? Почему бы не использовать kwargs["this"] там, где вам нужна переменная, особенно если она вам не нужна.

Можете ли вы предоставить нам реальный вариант использования, чтобы мы могли рассказать вам, как мы это сделаем?

person Natim    schedule 07.10.2020
comment
Привет @Natim, я предоставил более подробную информацию. Несмотря на это, мне нужно было распаковать без жесткого кода, так что это не сработает. Как я уже сказал g.d.d.c., я найду другой способ справиться с этим. - person Mike Williamson; 07.10.2020