2014-01-10 6 views
2

을 사용 (위치 또는 키워드)를 풀고있는 인수를 결정하고 내가 발견 한이 : 의 인트로 기능이 일부 인수를 풀기 위해 사용되는지 여부를 확인하는 나는 방법을 찾고 있었다

>>> def func_has_positional_args(func): 
    std_args = func.func_code.co_argcount 
    wildcard_args = len(func.func_code.co_varnames) - std_args 
    if wildcard_args == 2: 
     return True # yes, has both positional and keyword args 
    elif wildcard_args == 0: 
     return False # has neither positional, nor keyword args 
    else: 
     raise NotImplementedError('Unable to tell') 


>>> func_has_keyword_args = func_has_positional_args 
>>> def test1(a, b, *args, **kwargs): pass 

>>> func_has_positional_args(test1), func_has_keyword_args(test1) 
(True, True) 
>>> def test2(a, b): pass 

>>> func_has_positional_args(test2), func_has_keyword_args(test2) 
(False, False) 
>>> def test3(a, b, *args): pass 

>>> func_has_positional_args(test3) 

Traceback (most recent call last): 
    File "<pyshell#52>", line 1, in <module> 
    func_has_positional_args(test3) 
    File "<pyshell#41>", line 9, in func_has_positional_args 
    raise NotImplementedError('Unable to tell') 
NotImplementedError: Unable to tell 

그래서 나는 수 있어요 위치 정보가 없거나 언팩하는 키워드 인수가없는 경우 알려주십시오. 또한 둘 다 있는지 알 수 있지만 하나의 "와일드 카드"만있는 경우 어떤 "와일드 카드"형식 인수가 구현되었는지 구별 할 수 없습니다.

다음 결과를 얻을 수 있도록 도와 주시겠습니까?

# Already satisfied with above code: 
assert func_has_positional_args(test1) == True 
assert func_has_keyword_args(test1) == True 
assert func_has_positional_args(test2) == False 
assert func_has_keyword_args(test2) == False 

# Missing functionality (tests are failing): 
assert func_has_positional_args(test3) == True 
assert func_has_keyword_args(test3) == False 

또한이 기능 또는 동작과 관련하여 Python 3이 변경됩니까?

+3

... 내가 정말 밀접하게이 다음과 같은거야 모르겠지만, 당신은'inspect.getargspec'을 찾고 있지? 어떻게 다른 일을하고 있습니까? – mgilson

+0

@mgilson : 예, Bullseye;) 겉으로보기에 나는'inspect' 모듈을 보지 않고 함수 속성을 찾는 데 너무 집중했습니다 ... 대답으로 게시 하시겠습니까? – Tadeck

답변

3

mgilson이 주석 처리 한대로 inspect.getargspec (더 바람직하게는 Python 3.x에서 inspect.getfullargspec)을 사용하십시오.

import inspect 

def func_has_positional_args(func): 
    spec = inspect.getfullargspec(func) 
    return bool(spec.varargs) # varargs: name of the * argument or None 
def func_has_keyword_args(func): 
    spec = inspect.getfullargspec(func) 
    return bool(spec.varkw) # varkw: name of the ** argument or None 

예 :

>>> def test1(a, b, *args, **kwargs): pass 
... 
>>> def test2(a, b): pass 
... 
>>> def test3(a, b, *args): pass 
... 
>>> func_has_positional_args(test1) 
True 
>>> func_has_keyword_args(test1) 
True 
>>> func_has_positional_args(test2) 
False 
>>> func_has_keyword_args(test2) 
False 
>>> func_has_positional_args(test3) 
True 
>>> func_has_keyword_args(test3) 
False 
+0

파이썬 2.x + 3.x 호환 코드를 작성해 주셔서 감사합니다. 실제로'inspect'를 가져 오는 동안 실제로 그렇게하는 것이 맞습니까? 이 함수에 대한'six '모듈 지원을 찾지 못했습니다. – Tadeck

+0

@Tadeck, 파이썬 2와 3에서 둘 다 실행되는 코드를 원한다면'inspect.getargspec'을 사용하십시오. ('varkw'을'keywords'로 대체하십시오). – falsetru

+0

@Tadeck,'inspect.getargspec'은 문서에 따라 사용되지 않습니다. 그러나'getargspec'은 [Python 3.4] (http://docs.python.org/3.4/library/inspect.html#inspect.getargspec)에서도 여전히 존재합니다. – falsetru