В Python допускается несколько * (звездочка / звездочка) внутри вызова функции - PullRequest
0 голосов
/ 29 марта 2019

предположим, что есть общая функция:

def fn(*args, **kwargs):
return {"args":args,"kwargs":kwargs}

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

теперь предположим, что мы хотим вызывать эту функцию несколько раз, при этом некоторые из этих аргументов и kwargs остаются неизменными, а некоторые другие изменяются между каждым вызовом.

Один из способов достижения этого результата будет следующим:

result = [fn(*dargs, *args, **dkwargs, **kwargs) for dargs in dynamic_args for dkwargs in dynamic_kwargs]

, где dynamic_args может быть любым типом итерации (включая генераторы)

пример:

dynamic_args = [(1, 2, 3), (4, 6, 7), (8, 9, 0)]
dynamic_kwargs = [{"a": "A"}, {"b": "B"}, {"c": "C"}]
args = ("these", "are", "static", "args", )
kwargs = {"static": "kwarg"}

результат:

{'args': (1, 2, 3, 'these', 'are', 'static', 'args'), 'kwargs': {'a': 'A', 'static': 'kwarg'}}
{'args': (1, 2, 3, 'these', 'are', 'static', 'args'), 'kwargs': {'b': 'B', 'static': 'kwarg'}}
{'args': (1, 2, 3, 'these', 'are', 'static', 'args'), 'kwargs': {'c': 'C', 'static': 'kwarg'}}
{'args': (4, 5, 6, 'these', 'are', 'static', 'args'), 'kwargs': {'a': 'A', 'static': 'kwarg'}}
{'args': (4, 5, 6, 'these', 'are', 'static', 'args'), 'kwargs': {'b': 'B', 'static': 'kwarg'}}
{'args': (4, 5, 6, 'these', 'are', 'static', 'args'), 'kwargs': {'c': 'C', 'static': 'kwarg'}}
{'args': (7, 8, 9, 'these', 'are', 'static', 'args'), 'kwargs': {'a': 'A', 'static': 'kwarg'}}
{'args': (7, 9, 0, 'these', 'are', 'static', 'args'), 'kwargs': {'b': 'B', 'static': 'kwarg'}}
{'args': (8, 9, 0, 'these', 'are', 'static', 'args'), 'kwargs': {'c': 'C', 'static': 'kwarg'}}

iдумаю, что это работает, потому что когда вызывающая функция получает входные данные, аргументы * (kw) рассматриваются как продолжение аргументов d (kw), как единое целое (tuple, dict).

Проблема заключается в том, что ..мой линтер (flake8) видит это как ошибку InvalidSintax, следую ли я снова по хакерскому непитоническому пути?

и если да, есть ли другой способ получить тот же результат без добавления логики в код функции и, возможно, с сохранением синтаксиса понимания списка?

1 Ответ

1 голос
/ 30 марта 2019

У вас установлено flake8 только для Python 2, поэтому он анализирует ваш код в соответствии с правилами Python 2. См. http://flake8.pycqa.org/en/latest/user/invocation.html для использования flake8 для использования различных версий Python, которые вы, возможно, установили.

Однако вы можете написать свой код таким образом, чтобы он работал одинаково как в Python 2, так и в Python 3.

from itertools import chain


result = [fn(*chain(args, dargs),
             **dict(chain(kwargs.items(), dkwargs.items())))
          for dargs in dynamic_args 
          for dkwargs in dynamic_kwargs]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...