programing

함수가 받는 키워드 인수를 나열할 수 있습니까?

newnotes 2023. 9. 7. 22:02
반응형

함수가 받는 키워드 인수를 나열할 수 있습니까?

키워드 인수로 키/값을 전달해야 하는 딕션이 있습니다.예를 들면..

d_args = {'kw1': 'value1', 'kw2': 'value2'}
example(**d_args)

이것은 잘 작동하지만, d_args dict에 허용되지 않는 값이 있는 경우example기능적으로, 분명히 죽습니다.예를 들어, 예제 함수가 다음과 같이 정의되면def example(kw2):

이것은 제가 그들의 세대를 통제하지 않기 때문에 문제입니다.d_args, 아니면example기능..둘 다 외부 모듈에서 나온 것이고example명령어의 일부 키워드만 허용합니다.

이상적으로 나는 그냥 할 겁니다.

parsed_kwargs = feedparser.parse(the_url)
valid_kwargs = get_valid_kwargs(parsed_kwargs, valid_for = PyRSS2Gen.RSS2)
PyRSS2Gen.RSS2(**valid_kwargs)

아마 유효한 키워드-논술 목록에서 dict를 필터링 할 것입니다. 하지만 저는 궁금했습니다.특정 함수가 사용하는 키워드 인수를 프로그램적으로 나열하는 방법이 있습니까?

코드 개체를 직접 검사하고 변수를 계산하는 것보다 조금 더 나은 방법은 검사 모듈을 사용하는 것입니다.

>>> import inspect
>>> def func(a,b,c=42, *args, **kwargs): pass
>>> inspect.getargspec(func)
(['a', 'b', 'c'], 'args', 'kwargs', (42,))

특정 arg 집합으로 호출 가능한지 알고 싶다면 이미 지정된 기본값이 없는 arg가 필요합니다.다음을 통해 얻을 수 있습니다.

def get_required_args(func):
    args, varargs, varkw, defaults = inspect.getargspec(func)
    if defaults:
        args = args[:-len(defaults)]
    return args   # *args and **kwargs are not required, so ignore them.

그렇다면 특정 명령어에서 무엇을 놓쳤는지 알려주는 기능은 다음과 같습니다.

def missing_args(func, argdict):
    return set(get_required_args(func)).difference(argdict)

마찬가지로 잘못된 arg를 확인하려면 다음을 사용합니다.

def invalid_args(func, argdict):
    args, varargs, varkw, defaults = inspect.getargspec(func)
    if varkw: return set()  # All accepted
    return set(argdict) - set(args)

따라서 호출 가능한 경우 전체 테스트는 다음과 같습니다.

def is_callable_with_args(func, argdict):
    return not missing_args(func, argdict) and not invalid_args(func, argdict)

(이것은 python의 arg 구문 분석에만 적합합니다.런타임에서 잘못된 값을 확인합니다.kwargs분명히 탐지할 수 없습니다.)

이렇게 하면 모든 통과 가능 인수, 키워드 및 키워드가 아닌 인수의 이름이 인쇄됩니다.

def func(one, two="value"):
    y = one, two
    return y
print func.func_code.co_varnames[:func.func_code.co_argcount]

왜냐하면 첫번째로co_varnames는 항상 매개변수입니다(다음은 로컬 변수입니다. 예:y위의 예에서).

이제 다음과 같은 기능을 가질 수 있습니다.

def get_valid_args(func, args_dict):
    '''Return dictionary without invalid function arguments.'''
    validArgs = func.func_code.co_varnames[:func.func_code.co_argcount]
    return dict((key, value) for key, value in args_dict.iteritems() 
                if key in validArgs)

그러면 다음과 같이 사용할 수 있습니다.

>>> func(**get_valid_args(func, args))

만약 당신이 정말로 함수의 키워드 인수만 필요하다면, 당신은 사용할 수 있습니다.func_defaults추출할 속성:

def get_valid_kwargs(func, args_dict):
    validArgs = func.func_code.co_varnames[:func.func_code.co_argcount]
    kwargsLen = len(func.func_defaults) # number of keyword arguments
    validKwargs = validArgs[-kwargsLen:] # because kwargs are last
    return dict((key, value) for key, value in args_dict.iteritems() 
                if key in validKwargs)

이제 함수를 알려진 arg로 호출할 수 있지만 추출된 kwarg로 호출할 수 있습니다.

func(param1, param2, **get_valid_kwargs(func, kwargs_dict))

이는 다음과 같이 가정합니다.func소용없습니다*args아니면**kwargs그 표식에 깃든 주술

Python 3 솔루션의 경우 알고 싶은 매개 변수의 종류에 따라 사용 및 필터링할 수 있습니다.

positional 또는 키워드, 키워드 전용, var positional 및 var 키워드 파라미터를 사용한 샘플 기능 사용:

def spam(a, b=1, *args, c=2, **kwargs):
    print(a, b, args, c, kwargs)

서명 개체를 생성할 수 있습니다.

from inspect import signature
sig =  signature(spam)

그런 다음 목록 이해력으로 필터링하여 필요한 세부 정보를 확인합니다.

>>> # positional or keyword
>>> [p.name for p in sig.parameters.values() if p.kind == p.POSITIONAL_OR_KEYWORD]
['a', 'b']
>>> # keyword only
>>> [p.name for p in sig.parameters.values() if p.kind == p.KEYWORD_ONLY]
['c']

그리고 마찬가지로, 다양한 위치의 경우 다음을 사용합니다.p.VAR_POSITIONAL합니다 var를및다를을 입력합니다.VAR_KEYWORD.

또한 if에 절을 추가하여 다음을 확인하여 기본값이 존재하는지 확인할 수 있습니다.p.default 같은p.empty.

Python 3.0의 경우:

>>> import inspect
>>> import fileinput
>>> print(inspect.getfullargspec(fileinput.input))
FullArgSpec(args=['files', 'inplace', 'backup', 'bufsize', 'mode', 'openhook'],
varargs=None, varkw=None, defaults=(None, 0, '', 0, 'r', None), kwonlyargs=[], 
kwdefaults=None, annotations={})

함수 이름 'my fun'에 사용합니다.

myfun.__code__.co_varnames

DzinX의 답변 연장:

argnames = example.func_code.co_varnames[:func.func_code.co_argcount]
args = dict((key, val) for key,val in d_args.iteritems() if key in argnames)
example(**args)

많이 테스트하지는 않았지만 이 방법이 제 경우에 효과가 있을 것입니다.

import inspect


def example(arg_1: int, arg_2: list, arg_optional="Hello", *, kwarg, kwarg_optional="Hi"):
    pass


spec = inspect.getfullargspec(example)

args_required = spec.args
args_optional = args_required[-len(spec.defaults or []):]
args_required = args_required[:-len(args_optional)]

kwargs_required, kwargs_optional = spec.kwonlyargs, (spec.kwonlydefaults or {})
kwargs_required = [key for key in kwargs_required if key not in kwargs_optional]

unlimited_args, unlimited_kwargs = bool(spec.varargs), bool(spec.varkw)
annotations = spec.annotations

print(args_required, args_optional, kwargs_required, kwargs_optional, unlimited_args, unlimited_kwargs, annotations)

언급URL : https://stackoverflow.com/questions/196960/can-you-list-the-keyword-arguments-a-function-receives

반응형