То, что вы пытаетесь сделать, невозможно без уродливых хаков. Вы либо берете *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, а не для большинства других интерпретаторов. и это может сломаться в какой-то будущей версии, потому что довольно явно полагается на детали реализации интерпретатора.
person
abarnert
schedule
14.05.2018
*args
в качестве параметра. - person Code-Apprentice   schedule 14.05.2018a, b, c
параметрами, но затем использовать их какargs
. Вы делаете то или иное. Конечно, вы всегда можете написатьargs = a, b, c
в качестве первой строки функции, но я не уверен, что это вам даст. Возможно, если бы мы знали, почему вам это нужно, а не бессмысленную игрушечную задачку, мы могли бы объяснить что-то лучше. Но то, о чем вы просите, невозможно. - person abarnert   schedule 14.05.2018ff(a,b,c)
при создании определения функции и даже отредактированный вопрос, чтобы выделить его жирным шрифтом после того, как вы сделали свои комментарии к ответу, так что ... я думаю, даже если это то, что OP должен я> хочу, это не то, что хочет ОП. - person abarnert   schedule 14.05.2018getArgValueList()
, которую можно использовать внутри другой функции (имя аргумента явное), чтобы получить значение аргумента в виде списка - person user15964   schedule 14.05.2018def ff(*args)
. С другой стороны, если вы используете**kwargs
, вы можете очень близко подойти к тому, о чем просите. Я предлагаю вам прочитать ссылку над вашим вопросом для более подробной информации. - person Code-Apprentice   schedule 14.05.2018getArgValueList
, или привести более реалистичный пример того, что вы собираетесь с ней делать? Что бы вы ни пытались сделать, вероятно, есть лучший способ сделать это, даже если это не*args
. - person abarnert   schedule 14.05.2018f(a), f(b), ... on each of *args
. Тот, кого я связал, хочет позвонитьf(*args)
. Но все же это должен быть дубликат, пожалуйста, помогите определить, какой именно. - person smci   schedule 14.05.2018a = args[0], b = args[1]...
- person smci   schedule 14.05.2018