2017-02-20 3 views
2

Использование Python 3.x, я пытаюсь получить имя всех позиционных аргументов от некоторой функции, а именно:Получить имена позиционных аргументов из подписи функция в

def foo(a, b, c=1): 
    return 

Прямо сейчас я делаю это:

from inspect import signature, _empty 
args =[x for x, p in signature(foo).parameters.items() if p.default == _empty] 

Когда функция Alows * арг именно:

def foo(a, b, c=1, *args): 
    return 

Я добавив строку:

args.remove("args") 

Мне было интересно, есть ли лучший способ достичь этого.


Как suggested by Jim Fasarakis-Hilliard один лучший способ иметь дело с * ARGS случае использования Parameter.kind:

from inspect import signature, Parameter 
args =[] 
for x, p in signature(foo).parameters.items(): 
    if p.default == Parameter.empty and p.kind != Parameter.VAR_POSITIONAL: 
     args.append(x) 
+0

Обратите внимание, что 'args' - это просто« соглашение * * »: вы можете вызывать параметры, которые вы хотите, поэтому есть определенные случаи, когда это не будет работать. –

+0

Действительно, это одна из причин, почему я задаю вопрос. Прямо сейчас я использую это для своих собственных функций, и я следую конвенции args, но мне интересно, как добиться того же более «надежного» способа. –

ответ

4

Да, вы можете достичь более надежное решение путем дополнительной проверки, если .kind атрибут параметра не равно Parameter.VAR_POSITIONAL.

Для *args, это значение, которое устанавливается при создании объекта подписи из функции:

>>> def foo(a, b, c=1, *args): pass 
>>> print(signature(foo).parameters['args'].kind) 
VAR_POSITIONAL 

Так просто импортировать Parameter из inspect и добавить или условие, что kind != Parameter.VAR_POSITIONAL:

>>> from inspect import Parameter 
>>> Parameter.VAR_POSITIONAL == p['args'].kind 
True 
+0

Не лучше ли использовать '.kind' вместо' ._kind'? Атрибуты, начинающиеся с подчеркивания, считаются * private *. –

+0

Да @WillemVanOnsem, быстро набирает меня время от времени. –

+0

Спасибо! которые решают проблему * args. Хотя я все еще нашел понимание списка немного уродливым. –