[python] 파이썬 변수가 함수인지 어떻게 알 수 있습니까?

변수 x가 있으며 함수를 가리키는 지 여부를 알고 싶습니다.

나는 다음과 같은 일을 할 수 있기를 바랐다.

>>> isinstance(x, function)

그러나 그것은 나에게 준다 :

Traceback (most recent call last):
  File "<stdin>", line 1, in ?
NameError: name 'function' is not defined

내가 선택한 이유는

>>> type(x)
<type 'function'>



답변

Python 2.x 또는 Python 3.2 이상인 경우을 사용할 수도 있습니다 callable(). 더 이상 사용되지 않았지만 이제는 사용되지 않으므로 다시 사용할 수 있습니다. http://bugs.python.org/issue10518 에서 토론을 읽을 수 있습니다 . 당신은 이것을 할 수 있습니다 :

callable(obj)

이것이 Python 3.x 용이지만 3.2 이전 인 경우 객체에 __call__속성 이 있는지 확인하십시오 . 당신은 이것을 할 수 있습니다 :

hasattr(obj, '__call__')

자주 제안되는 types.FunctionTypes접근 방식은 내장과 같이 아마도 전달하려는 많은 경우를 다루지 않기 때문에 올바르지 않습니다.

>>> isinstance(open, types.FunctionType)
False

>>> callable(open)
True

오리 유형 개체의 속성을 확인하는 올바른 방법은 오리 크기의 컨테이너에 맞는지 확인하지 말고 떨리는 지 묻는 것입니다. types.FunctionType함수가 무엇인지에 대한 구체적인 아이디어가 없다면 사용 하지 마십시오 .


답변

내장 네임 스페이스에 생성자가없는 내장 유형 (예 : 함수, 생성기, 메서드)이 types모듈에 있습니다. 당신은 사용할 수 있습니다 types.FunctionTypeisinstance전화 :

In [1]: import types
In [2]: types.FunctionType
Out[2]: <type 'function'>
In [3]: def f(): pass
   ...:
In [4]: isinstance(f, types.FunctionType)
Out[4]: True
In [5]: isinstance(lambda x : None, types.FunctionType)
Out[5]: True

여기에는 일반적으로 필요하지 않은 매우 구체적인 “기능”개념이 사용됩니다. 예를 들어 zip(기술적으로 클래스)를 거부합니다 .

>>> type(zip), isinstance(zip, types.FunctionType)
(<class 'type'>, False)

open (내장 함수의 유형이 다릅니다) :

>>> type(open), isinstance(open, types.FunctionType)
(<class 'builtin_function_or_method'>, False)

random.shuffle(숨겨진의 기술적 방법 random.Random예) :

>>> type(random.shuffle), isinstance(random.shuffle, types.FunctionType)
(<class 'method'>, False)

types.FunctionType바이트 코드를 디 컴파일하거나 클로저 변수를 검사하는 것과 같이 인스턴스에 특정한 작업을 수행하는 경우을 사용 types.FunctionType하지만 함수처럼 호출 할 수있는 객체가 필요한 경우을 사용하십시오 callable.


답변

Python 2.1부터는 모듈 isfunction에서 가져올 수 있습니다 inspect.

>>> from inspect import isfunction
>>> def f(): pass
>>> isfunction(f)
True
>>> isfunction(lambda x: x)
True


답변

받아 들여진 대답은 정확한 것으로 생각되었을 당시에있었습니다. 결과적 으로 파이썬 3.2에서는 다시 대체 할 것이 없습니다callable() . 특히 테스트중인 객체 callable()tp_call필드를 확인합니다 . 파이썬과 동등한 것은 없습니다. 제안 된 테스트의 대부분은 대부분 올바른 시간입니다.

>>> class Spam(object):
...     def __call__(self):
...         return 'OK'
>>> can_o_spam = Spam()


>>> can_o_spam()
'OK'
>>> callable(can_o_spam)
True
>>> hasattr(can_o_spam, '__call__')
True
>>> import collections
>>> isinstance(can_o_spam, collections.Callable)
True

__call__클래스에서 를 제거하여 멍키 렌치를 던질 수 있습니다 . 그리고 일을 더욱 흥미롭게 유지 __call__하려면 인스턴스에 가짜 를 추가하십시오 !

>>> del Spam.__call__
>>> can_o_spam.__call__ = lambda *args: 'OK?'

이것은 실제로 호출 할 수 없습니다.

>>> can_o_spam()
Traceback (most recent call last):
  ...
TypeError: 'Spam' object is not callable

callable() 올바른 결과를 반환합니다.

>>> callable(can_o_spam)
False

그러나 hasattr입니다 잘못된 :

>>> hasattr(can_o_spam, '__call__')
True

can_o_spam결국 그 속성을 가지고 있습니다; 인스턴스를 호출 할 때 사용되지 않습니다.

더 미묘한 것도이 isinstance()잘못됩니다.

>>> isinstance(can_o_spam, collections.Callable)
True

이 검사를 앞뒤로 사용하여 메소드를 삭제 했으므로 abc.ABCMeta
결과를 캐시합니다. 아마도 이것은의 버그입니다 abc.ABCMeta. 즉, 정말 어떤 가능한 방법이 말했다 사용하여보다 결과보다 더 정확한 결과 생산 callable()이후, 자신을 typeobject->tp_call
슬롯 방법은 다른 방법으로 액세스 할 수 없습니다가.

그냥 사용 callable()


답변

다음은 부울을 반환해야합니다.

callable(x)


답변

파이썬의 2to3 도구 ( http://docs.python.org/dev/library/2to3.html )는 다음을 제안합니다.

import collections
isinstance(obj, collections.Callable)

http://bugs.python.org/issue7006hasattr(x, '__call__') 때문에이 방법 대신 선택한 것으로 보입니다 .


답변

callable(x) 전달 된 객체를 Python에서 호출 할 수 있으면 함수가 true 반환하지만 함수가 Python 3.0에 존재하지 않으며 올바르게 말하면 다음을 구별하지 못합니다.

class A(object):
    def __call__(self):
        return 'Foo'

def B():
    return 'Bar'

a = A()
b = B

print type(a), callable(a)
print type(b), callable(b)

당신은 얻을 것이다 <class 'A'> True<type function> True출력으로.

isinstance무언가가 함수인지 확인하기 위해 완벽하게 작동합니다 (시도 isinstance(b, types.FunctionType)). 무언가를 불러 낼 수 있는지 정말로 알고 싶다면 hasattr(b, '__call__')그것을 사용 하거나 시도해보십시오.

test_as_func = True
try:
    b()
except TypeError:
    test_as_func = False
except:
    pass

물론 이것은 호출 가능 여부를 알려주지 않지만 TypeError처음 실행될 때 호출 할 수 있는지 또는 호출 할 수 없는지를 나타 냅니다. 그것은 당신에게 중요하지 않을 수 있습니다.