То, что вы пытаетесь сделать, невозможно без безобразных хаков. Вы либо берете *args
и получаете последовательность значений параметров, которую вы можете использовать как args
:
def ff(*args):
return list(map(myfunc, args))
… или вы берете три явных параметра и используете их по имени:
def ff(a, b, c):
return list(map(myfunc, (a, b, c)))
… но это одно или другое, а не оба.
Конечно, вы можете поместить эти значения в последовательность самостоятельно, если хотите:
def ff(a, b, c):
args = a, b, c
return list(map(myfunc, args))
… но я не уверен, что это тебя покупает.
Если вы действительно хотите знать, как написать функцию getArgValueList
, я объясню, как это сделать. Однако, если вы хотите сделать свой код более читабельным, более эффективным, более идиоматичным, более простым для понимания, более кратким или почти чем-либо еще, это будет иметь прямо противоположный эффект. Единственная причина, по которой я могу себе представить, что делать что-то подобное, это то, что вам приходилось генерировать функции динамически или что-то в этом роде, и даже тогда я не могу придумать причину, по которой вы не могли бы просто использовать *args
. Но, если вы настаиваете:
def getArgValueList():
frame = inspect.currentframe().f_back
code = frame.f_code
vars = code.co_varnames[:code.co_argcount]
return [frame.f_locals[var] for var in vars]
Если вы хотите узнать, как это работает, большая часть находится в inspect
модульной документации:
currentframe()
получает текущий кадр - кадр getArgValueList
.
f_back
получает родительский кадр - кадр того, кто вызвал getArgValueList
.
f_code
получает объект кода, скомпилированный из тела функции того, кто вызвал getArgValueList
.
co_varnames
- список всех локальных переменных в этом теле, начиная с параметров.
co_argcount
- это число явных параметров позиционных или ключевых слов.
f_locals
- это диктант с копией locals()
окружения фрейма.
Это, конечно, работает только для функции, которая не принимает *args
, аргументы только для ключевых слов или **kwargs
, но вы можете расширить ее, чтобы работать с ними также, немного поработав. (Подробнее см. co_kwonlyargcount
, co_flags
, CO_VARARGS
и CO_VARKEYWORDS
.)
Кроме того, это работает только для CPython, но не для большинства других интерпретаторов. и он может сломаться в какой-то будущей версии, потому что он довольно явно полагается на детали реализации интерпретатора.