Если это дублирующий вопрос, заранее извиняюсь .. Я хотел бы лучше понять, что такое ** kwargs в python, и на самом деле надеялся написать функцию, которая могла бы обрабатывать распаковку и внутреннюю ссылку на key:value
пары для передачи ** аргументов kwargs.
Мой маленький пример выглядит следующим образом:
arguments = {'apple': 50, 'zoom': 'foo', 'bar': True}
Я хотел бы иметь возможность ссылаться на ключи и значениясловаря, переданного в функцию, без явной ссылки на них из самой функции.
def test(**kwargs):
if kwargs is not None:
print(f'apple: {apple}')
print(f'zoom: {zoom}')
print(f'bar: {bar}')
Вызов вышеупомянутого через test(**arguments)
, конечно, не удался, но есть ли способ "распаковать" ** kwargs в локальное пространство имен внутри функции, чтобы выполнить то, о чем я думаю?
Одна вещь, которую я рассмотрел, - это создать словарь внутри функции и затем использовать exec()
для компиляции пар ключ: значение в этот словарь пространства имен, но это кажется немного сложным.
Есть ли другой способ присвоения локальных переменных из ** kwargs непосредственно в функцию?
Заранее спасибо.
РЕДАКТИРОВАТЬ
Я также исследовал с использованием vars()
и написал следующее:
def test(**kwargs):
try:
print(**vars())
except Exception as e:
print(e, '\n\n')
print(vars())
if kwargs is not None:
try:
print(f'apple: {apple}')
print(f'zoom: {zoom}')
print(f'bar: {bar}')
except:
for k, v in kwargs.items():
print(f'k: {k} : v: {v}')
Со следующим выводом:
'kwargs' is an invalid keyword argument for this function
{'kwargs': {'apple': 50, 'zoom': 'foo', 'bar': True}, 'e':TypeError("'kwargs' is an invalid keyword argument for this function",)}
k: apple : v: 50
k: zoom : v: foo
k: bar : v: True
Я заметил, что print(**kwargs)
пытается получить доступ к "kwargs" как к именованной переменной.Я предполагаю, что вопрос, который я пытаюсь решить, если определение функции с аргументами по умолчанию, то передача ** kwargs решит проблему?Я могу попробовать это и посмотреть, работает ли он, и обновить ..
РЕДАКТИРОВАТЬ II
Это работает .. Похоже, определение функции с именованными значениями по умолчанию позволило мнессылаться на эти переменные непосредственно из ** kwargs, но это не влечет за собой ссылки на словарь ** kwargs и знания ключей в любом случае.
arguments = {'apple': 50, 'zoom': 'foo', 'bar': True, 'baz': 99}
def test(apple = None, zoom = 'fee', bar = False, **kwargs):
if kwargs is not None:
try:
print(f'apple: {apple}')
print(f'zoom: {zoom}')
print(f'bar: {bar}')
except Exception as e:
print(e, '\n\n\n')
for k, v in kwargs.items():
print(f'k: {k} : v: {v}')
test(**arguments)
РЕДАКТИРОВАТЬ III: update
Следующее является наиболее близким к тому, что я изначально пытался передать и реализовать.Функция, которая обрабатывает произвольные пользовательские ключевые аргументы и связывает их с переменными в локальном пространстве имен ...
def test(**kwargs):
ns = {}
args_string = ''
for k, v in kwargs.items():
print(f'k: {k}, v: {v}')
try:
args_string += str(k) + '=' + '{}'.format(int(v))+'\n'
except:
args_string += str(k) + '=' + '"{}"'.format(str(v))+'\n'
exec(args_string, ns)
return {k:v for k, v in ns.items() if k in kwargs.keys() }
Запуск следующего позволяет мне получить доступ к переменным, но я подозреваю, что это небезопасный или "хороший" код,
locals().update(test(**arguments))