문제

키워드 인수로 키/값을 전달 해야하는 DITT가 있습니다. 예를 들어 ..

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

이것은 잘 작동합니다. 하지만 d_args dict에 값이있는 경우 example 함수, 분명히 죽는다 .. 예제 함수가 다음과 같이 정의되면 def example(kw2):

나는 내가 생성을 제어하지 않기 때문에 문제입니다. d_args, 아니면 그 example 기능 .. 둘 다 외부 모듈에서 나와 example DICT에서 키워드 변호 중 일부만 받아들입니다.

이상적으로는 그냥 할 것입니다

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 세트로 호출 가능한지 알고 싶다면 기본값이 이미 지정되지 않은 Args가 필요합니다. 이것들은 다음과 같이받을 수 있습니다.

def getRequiredArgs(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.

그런 다음 특정 DITT에서 누락 된 내용을 알리는 기능은 다음과 같습니다.

def missingArgs(func, argdict):
    return set(getRequiredArgs(func)).difference(argdict)

마찬가지로 유효하지 않은 Args를 확인하려면 사용하십시오.

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

그리고 호출 가능한 경우 전체 테스트는 다음과 같습니다.

def isCallableWithArgs(func, argdict):
    return not missingArgs(func, argdict) and not invalidArgs(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 getValidArgs(func, argsDict):
    '''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 argsDict.iteritems() 
                if key in validArgs)

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

>>> func(**getValidArgs(func, args))

편집하다: 작은 추가 : 당신이 있다면 키워드 인수 만 있으면됩니다 함수의 경우 사용할 수 있습니다 func_defaults 추출에 대한 속성 :

def getValidKwargs(func, argsDict):
    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 argsDict.iteritems() 
                if key in validKwargs)

이제 알려진 args로 기능을 호출 할 수 있지만 kwargs를 추출했습니다.

func(param1, param2, **getValidKwargs(func, kwargsDict))

이것은 그것을 가정합니다 func 아니오를 사용합니다 *args 또는 **kwargs 서명의 마법.

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={})

Python 3 솔루션의 경우 사용할 수 있습니다 inspect.signature 그리고 다음에 따라 필터 매개 변수의 종류 당신은 알고 싶습니다.

위치 또는 키워드, 키워드 전용, VAR 위치 및 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']

그리고 유사하게, var 포지션을 사용하는 경우 p.VAR_POSITIONAL 그리고 var 키워드 VAR_KEYWORD.

또한 IF에 절을 추가하여 p.default 동등합니다 p.empty.

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)
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top