2012-11-29 3 views
9

함수가 빈 정의인지 아닌지를 알아야합니다.파이썬에서 빈 함수 정의를 감지하십시오.

def foo(): 
    pass 

또는 같은 :

def foo(i, *arg, **kwargs): 
    pass 

또는 같은 :

foo = lambda x: None 

(가) 모듈을 '검사'를 사용을 감지하는 가장 우아한 방법은 무엇입니까 그것은처럼 될 수 있을까? 이것보다 좋은 방법이 있습니까 :

def isEmptyFunction(func): 
    e = lambda: None 
    return func.__code__.co_code == e.__code__.co_code 
+0

: 내 목적을 위해

, 그냥 테스트하기 위해 추가로 케이스를 추가하기 위해 노력하고 있습니다. 그 후에는 즉시 ":"및 "통과"또는 "없음"을 찾습니다. 깨끗하지는 않지만 이것이 효과가 있다고 생각합니다. – spicavigo

+0

또 다른 방법은 ast 모듈을 사용하고 함수 문자열을 구문 분석하는 것입니다. 나는 당신이 세부 사항을 해결할 수 있다고 생각합니다. – spicavigo

+3

당신이하고있는 방식이 괜찮아 보입니다. – BrenBarn

답변

1

사용하는 방식에 따라 다릅니다. 아마도 "우아한"해결책은 함수 목록을 가지고 비어있는 (또는 비공개가 아닌) 모든 함수에 목록에 추가 한 다음 함수가 목록에 있는지 아닌지 확인하는 것입니다 .

-2

왜 그렇게할까요? 그것은 나쁜 디자인처럼 보입니다. 나는 당신이 더 빨리 아무것도하지 않을 것이라고 확신합니다.

python -m timeit -s'def a(): pass' -s'def b(): pass' 'if a.__code__.co_code == b.__code__.co_code: pass' 
1000000 loops, best of 3: 0.293 usec per loop 

python -m timeit -s 'def a(): pass' -s 'def b(): pass' 'a()' 
10000000 loops, best of 3: 0.0941 usec per loop 

후자의 시간에는 10 배 이상의 루프가 있었기 때문에 전화를하는 것보다 비교하는 것이 더 느린 것처럼 보입니다. equals 연산자는 실제로 a를 반드시 호출합니다. 코드 .co_code. eq. 그래서 당신은 일을 천천히하고 있습니다.

4

docstring이있는 빈 함수의 바이트 코드가 약간 다르므로 제안한 메서드가 제대로 작동하지 않습니다.

docstring이없는 빈 함수에 대한 func.__code__.co_code의 값은 'd\x00\x00S'이고 docstring이있는 함수의 값은 'd\x01\x00S'입니다. 당신은 generate_tokens를 사용하여 토큰 "DEF"또는 "람다"로 시작하면 확인할 수 있습니다

def isEmptyFunction(func): 
    def empty_func(): 
     pass 

    def empty_func_with_doc(): 
     """Empty function with docstring.""" 
     pass 

    return func.__code__.co_code == empty_func.__code__.co_code or \ 
     func.__code__.co_code == empty_func_with_doc.__code__.co_code