source

변수가 함수인지 아닌지는 어떻게 검출합니까?

ittop 2023. 4. 17. 22:28
반응형

변수가 함수인지 아닌지는 어떻게 검출합니까?

변수입니다.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+ 용이라면 를 사용할 수 있습니다.이전에는 사용되지 않았지만 지금은 사용되지 않으므로 다시 사용할 수 있습니다.토론은 http://bugs.python.org/issue10518에서 보실 수 있습니다.이 조작은, 다음과 같이 실행할 수 있습니다.

callable(obj)

3.x지만 3. 버전인 에 Python 3.x 3.2가 합니다.__call__이렇게 하다, 이렇게하면 .

hasattr(obj, '__call__')

자주 제안되는 접근법(둘 다 정확히 동일한 작업을 수행함)에는 몇 가지 경고가 수반됩니다.다시 돌아오다False비 Python 함수의 경우.예를 들어 대부분의 빌트인 함수는 Python이 아닌 C로 구현되어 있기 때문에 반환됩니다.False:

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

types.FunctionType을 사용법오리형 물체의 특성을 확인하는 적절한 방법은 울음소리 여부를 물어보는 것이지 오리형 물체의 크기가 맞는지 확인하는 것이 아니다.

를 들어 은 에 .types, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아.types.FunctionType an isinstance 삭제:

>>> import types
>>> types.FunctionType
<class 'function'>

>>> def f(): pass

>>> isinstance(f, types.FunctionType)
True
>>> isinstance(lambda x : None, types.FunctionType)
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(hidden) )random.Random★★★★★★★★★★★★★★★★★★:

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

특정한 types.FunctionType이나 폐쇄""를 사용합니다.types.FunctionType에는 ", " "를 callable.

Python 2.1부터 Import 할 수 있습니다.isfunction를 참조해 주세요.

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

받아들여진 대답은 그것이 옳다고 생각될 때였다.알고 보니 을 대신할 수 있는 것은 없다callable()3.으로는 Python 3.2로 되어 있다.★★★★★★★★★★★★★★★★,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속죄하다인스턴스를 호출할 때 사용되지 않을 뿐입니다.

미묘하게 말하면, 씬 even even even even even even even even even even even even evenisinstance()것도틀틀 틀틀틀다다

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

이를 삭제했기 에 이 체크는 삭제되었습니다.abc.ABCMeta을 사용하다 거거틀 in in in in in in in arguably in in in in in in in in에 있는 버그입니다.abc.ABCMeta하지만 결과보다 더 정확한 결과를 얻을 수 있는 방법은 없습니다.callable() 자체, 그 typeobject->tp_call다른 으로 액세스할 수 .

쓰세요.callable()

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

callable(x)

결과

호출 가능(x) hasattr(x, '_call__') inspect.isfunction(x) inspect.ismethod(x) inspect.isgenerator 함수(x) inspect.iscoroutine 함수(x) inspect.isasyncgenfunction(x) isinstance(x, 입력).콜 가능) isinstance(x, type).빌트인 펑션 타입) isinstance(x, type).내장 Method Type) isinstance(x, type).기능 타입) isinstance(x, type).메서드 타입) isinstance(x, type).람다 타입) isinstance(x, functools.syslog)
인쇄물 × × × × × × × × ×
기능하다 × × × × × × × ×
functools.displaces × × × × × × × × × ×
<420da> × × × × × × × ×
발전기 × × × × × × ×
비동기_펑크 × × × × × × ×
비동기_비동기 × × × × × × ×
A × × × × × × × × × × ×
메트 × × × × × × × ×
클래스 방식 × × × × × × × × ×
정적 방법 × × × × × × × ×
import types
import inspect
import functools
import typing


def judge(x):
    name = x.__name__ if hasattr(x, '__name__') else 'functools.partial'
    print(name)
    print('\ttype({})={}'.format(name, type(x)))
    print('\tcallable({})={}'.format(name, callable(x)))
    print('\thasattr({}, \'__call__\')={}'.format(name, hasattr(x, '__call__')))
    print()
    print('\tinspect.isfunction({})={}'.format(name, inspect.isfunction(x)))
    print('\tinspect.ismethod({})={}'.format(name, inspect.ismethod(x)))
    print('\tinspect.isgeneratorfunction({})={}'.format(name, inspect.isgeneratorfunction(x)))
    print('\tinspect.iscoroutinefunction({})={}'.format(name, inspect.iscoroutinefunction(x)))
    print('\tinspect.isasyncgenfunction({})={}'.format(name, inspect.isasyncgenfunction(x)))
    print()
    print('\tisinstance({}, typing.Callable)={}'.format(name, isinstance(x, typing.Callable)))
    print('\tisinstance({}, types.BuiltinFunctionType)={}'.format(name, isinstance(x, types.BuiltinFunctionType)))
    print('\tisinstance({}, types.BuiltinMethodType)={}'.format(name, isinstance(x, types.BuiltinMethodType)))
    print('\tisinstance({}, types.FunctionType)={}'.format(name, isinstance(x, types.FunctionType)))
    print('\tisinstance({}, types.MethodType)={}'.format(name, isinstance(x, types.MethodType)))
    print('\tisinstance({}, types.LambdaType)={}'.format(name, isinstance(x, types.LambdaType)))
    print('\tisinstance({}, functools.partial)={}'.format(name, isinstance(x, functools.partial)))


def func(a, b):
    pass


partial = functools.partial(func, a=1)

_lambda = lambda _: _


def generator():
    yield 1
    yield 2


async def async_func():
    pass


async def async_generator():
    yield 1


class A:
    def __call__(self, a, b):
        pass

    def meth(self, a, b):
        pass

    @classmethod
    def classmeth(cls, a, b):
        pass

    @staticmethod
    def staticmeth(a, b):
        pass


for func in [print,
             func,
             partial,
             _lambda,
             generator,
             async_func,
             async_generator,
             A,
             A.meth,
             A.classmeth,
             A.staticmeth]:
    judge(func)

시간을

가장 일반적인 세 가지 방법을 선택합니다.

시간/초
호출 가능(x) 0.86
hasattr(x, '_call__') 1.36
isinstance(x, 입력).콜 가능) 12.19
import typing
from timeit import timeit


def x():
    pass


def f1():
    return callable(x)


def f2():
    return hasattr(x, '__call__')


def f3():
    return isinstance(x, typing.Callable)


print(timeit(f1, number=10000000))
print(timeit(f2, number=10000000))
print(timeit(f3, number=10000000))
# 0.8643081
# 1.3563508
# 12.193492500000001

Python의 2to3 툴(http://docs.python.org/dev/library/2to3.html)은 다음을 제안합니다.

import collections
isinstance(obj, collections.Callable)

은 'VIP'가 아닌 'VIP'가 된 것 .hasattr(x, '__call__')http://bugs.python.org/issue7006이 원인입니다.

callable(x) 전달된 객체가 Python에서 호출될 수 있지만 함수가 Python 3.0에 존재하지 않는 경우 true가 반환되며, 적절하게 말하면 다음 항목이 구분되지 않습니다.

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실행 중이거나 애초에 호출할 수 없는 경우.그건 너한테 중요하지 않을 수도 있어.

함수, 메서드, 삽입 fun/method, lamda 등 구문적으로 함수와 같은 모든 것을 검출하는 경우 호출 가능한 오브젝트(이 오브젝트)는 제외합니다.__call__ defined)이 합니다: method defined)츠키다

import types
isinstance(x, (types.FunctionType, types.BuiltinFunctionType, types.MethodType, types.BuiltinMethodType, types.UnboundMethodType))

했습니다.is*()inspect 및 더 합니다.

를 사용해 보겠습니다.

발췌:

object 인수가 호출 가능한 것으로 나타나면 True를 반환하고 그렇지 않으면 False를 반환합니다.

배웠으면C++ 있을 function object ★★★★★★★★★★★★★★★★★」functor , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ,be called as if it is a function.

에서는 C++입니다.an ordinary function오브젝트이며 으로 '함수 포인터'를 정의하는 입니다.더 일반적으로 를 정의하는 클래스의 오브젝트도 마찬가지입니다.operator()에서는 C++11 입니다the lambda expression는 는 입니다.functor

에서는 Python, Python의functors ★★★★callableAn ordinary function를 호출할 수 .a lambda expression를 호출할 수 .functional.partial수 는 호출할 수 있습니다.class with a __call__() method를 호출할 수 있습니다.


그럼 ' 아, 아, 아, 아, 아, 아, 아, 아, 맞다.I have a variable, x, and I want to know whether it is pointing to a function or not.

하려면 그 와 같은 .callable @John Feminella

judge whether a object is just an ordinary function or not인스턴스 식 ), 에 (호출 가능한 클래스 인스턴스 또는 식 아님xtypes.XXX에 의해 제안하다@Ryan더 나은 선택입니다.

그런 다음 이 코드를 사용하여 실험을 합니다.

#!/usr/bin/python3
# 2017.12.10 14:25:01 CST
# 2017.12.10 15:54:19 CST

import functools
import types
import pprint

클래스 및 일반 함수를 정의합니다.

class A():
    def __call__(self, a,b):
        print(a,b)
    def func1(self, a, b):
        print("[classfunction]:", a, b)
    @classmethod
    def func2(cls, a,b):
        print("[classmethod]:", a, b)
    @staticmethod
    def func3(a,b):
        print("[staticmethod]:", a, b)

def func(a,b):
    print("[function]", a,b)

펑터를 정의합니다.

#(1.1) built-in function
builtins_func = open
#(1.2) ordinary function
ordinary_func = func
#(1.3) lambda expression
lambda_func  = lambda a : func(a,4)
#(1.4) functools.partial
partial_func = functools.partial(func, b=4)

#(2.1) callable class instance
class_callable_instance = A()
#(2.2) ordinary class function
class_ordinary_func = A.func1
#(2.3) bound class method
class_bound_method = A.func2
#(2.4) static class method
class_static_func = A.func3

펑터의 리스트와 타입의 리스트를 정의합니다.

## list of functors
xfuncs = [builtins_func, ordinary_func, lambda_func, partial_func, class_callable_instance, class_ordinary_func, class_bound_method, class_static_func]
## list of type
xtypes = [types.BuiltinFunctionType, types.FunctionType, types.MethodType, types.LambdaType, functools.partial]

웨더 판사는 펑터를 호출할 수 있다.보시다시피 모두 호출할 수 있습니다.

res = [callable(xfunc)  for xfunc in xfuncs]
print("functors callable:")
print(res)

"""
functors callable:
[True, True, True, True, True, True, True, True]
"""

펑터의 타입(타입)을 판단합니다.XXX)의 경우 함수의 유형이 모두 동일하지는 않습니다.

res = [[isinstance(xfunc, xtype) for xtype in xtypes] for xfunc in xfuncs]

## output the result
print("functors' types")
for (row, xfunc) in zip(res, xfuncs):
    print(row, xfunc)

"""
functors' types
[True, False, False, False, False] <built-in function open>
[False, True, False, True, False] <function func at 0x7f1b5203e048>
[False, True, False, True, False] <function <lambda> at 0x7f1b5081fd08>
[False, False, False, False, True] functools.partial(<function func at 0x7f1b5203e048>, b=4)
[False, False, False, False, False] <__main__.A object at 0x7f1b50870cc0>
[False, True, False, True, False] <function A.func1 at 0x7f1b5081fb70>
[False, False, True, False, False] <bound method A.func2 of <class '__main__.A'>>
[False, True, False, True, False] <function A.func3 at 0x7f1b5081fc80>
"""

데이터를 사용하여 호출 가능한 함수의 유형을 표로 작성합니다.

여기에 이미지 설명 입력

그런 다음 적절한 펑터의 유형을 선택할 수 있습니다.

예를 들어 다음과 같습니다.

def func(a,b):
    print("[function]", a,b)

>>> callable(func)
True
>>> isinstance(func,  types.FunctionType)
True
>>> isinstance(func, (types.BuiltinFunctionType, types.FunctionType, functools.partial))
True
>>> 
>>> isinstance(func, (types.MethodType, functools.partial))
False

승인된 답변으로 John Feminella는 다음과 같이 말했다.

오리형 물체의 특성을 확인하는 적절한 방법은 울음소리 여부를 물어보는 것이지 오리형 물체의 크기가 맞는지 확인하는 것이 아니다.「직접 비교」의 어프로치는, 빌트인등의 많은 기능에 대해서 오답이 됩니다.

함수를 엄밀하게 구별하기 위한 두 가지 립이 있지만, 나는 포괄적인 비교 표를 그립니다.

8.9. types - 동적 유형 작성 및 삽입 유형 이름 - Python 3.7.0 설명서

30.13. 검사 - 활성 객체 검사 - Python 3.7.0 설명서

#import inspect             #import types
['isabstract',
 'isasyncgen',              'AsyncGeneratorType',
 'isasyncgenfunction', 
 'isawaitable',
 'isbuiltin',               'BuiltinFunctionType',
                            'BuiltinMethodType',
 'isclass',
 'iscode',                  'CodeType',
 'iscoroutine',             'CoroutineType',
 'iscoroutinefunction',
 'isdatadescriptor',
 'isframe',                 'FrameType',
 'isfunction',              'FunctionType',
                            'LambdaType',
                            'MethodType',
 'isgenerator',             'GeneratorType',
 'isgeneratorfunction',
 'ismethod',
 'ismethoddescriptor',
 'ismodule',                'ModuleType',        
 'isroutine',            
 'istraceback',             'TracebackType'
                            'MappingProxyType',
]

'덕 타이핑'은 일반적인 용도로 권장되는 솔루션입니다.

def detect_function(obj):
    return hasattr(obj,"__call__")

In [26]: detect_function(detect_function)
Out[26]: True
In [27]: callable(detect_function)
Out[27]: True

빌트인 기능에 대해서

In [43]: callable(hasattr)
Out[43]: True

내장 기능 또는 사용자 정의 기능 중 어느 것을 한 단계 더 진행됩니다.

#check inspect.isfunction and type.FunctionType
In [46]: inspect.isfunction(detect_function)
Out[46]: True
In [47]: inspect.isfunction(hasattr)
Out[47]: False
In [48]: isinstance(detect_function, types.FunctionType)
Out[48]: True
In [49]: isinstance(getattr, types.FunctionType)
Out[49]: False
#so they both just applied to judge the user-definded

다음 중 어느 쪽인가builtin function

In [50]: isinstance(getattr, types.BuiltinFunctionType)
Out[50]: True
In [51]: isinstance(detect_function, types.BuiltinFunctionType)
Out[51]: False

요약

callable
types.BuiltinFunctionType더 구체적인 요구가 있는 경우.

정확한 함수 검사기

콜러블은 매우 좋은 솔루션입니다.하지만 저는 존 페미넬라와는 정반대의 방법으로 이것을 다루고 싶었습니다.이런 말을 하는 대신

오리형 물체의 특성을 확인하는 적절한 방법은 울음소리 여부를 물어보는 것이지 오리형 물체의 크기가 맞는지 확인하는 것이 아니다.「직접 비교」의 어프로치는, 빌트인등의 많은 기능에 대해서 오답이 됩니다.

다음과 같이 처리하겠습니다.

어떤 것이 오리인지 확인하는 적절한 방법은 울음소리를 낼 수 있는지 확인하는 것이 아니라, 단지 겉으로 봤을 때 오리처럼 보이는지 확인하는 것이 아니라 몇 가지 필터를 통해 그것이 진짜 오리인지 확인하는 것이다.

구현 방법

'유형' 모듈에는 기능을 감지하는 클래스가 많이 있으며, 가장 유용한 유형은 유형입니다.기능유형이지만 방법 유형, 내장 유형, 람다 유형 등 다른 유형도 많이 있습니다.또, 「functools.partial」오브젝트를 함수로 간주합니다.

이 함수가 함수인지 여부를 확인하는 간단한 방법은 이러한 모든 유형에서 isinstance 조건을 사용하는 것입니다.이전에는 위의 모든 것을 계승하는 베이스 클래스를 만들고 싶었지만, Python에서는 위의 클래스 중 일부를 계승할 수 없기 때문에 만들 수 없습니다.

다음은 어떤 클래스를 분류할 수 있는 함수의 표입니다.

kinght-ht의 함수 테이블 위의 기능 테이블 by kinght-table

그것을 실현하는 코드

이것은 위에서 설명한 모든 작업을 수행하는 코드입니다.

from types import BuiltinFunctionType, BuiltinMethodType,  FunctionType, MethodType, LambdaType
from functools import partial

def is_function(obj):
  return isinstance(obj, (BuiltinFunctionType, BuiltinMethodType,  FunctionType, MethodType, LambdaType, partial))

#-------------------------------------------------

def my_func():
  pass

def add_both(x, y):
  return x + y

class a:
  def b(self):
    pass

check = [

is_function(lambda x: x + x),
is_function(my_func),
is_function(a.b),
is_function(partial),
is_function(partial(add_both, 2))

]

print(check)
>>> [True, True, True, False, True]

한 가지 잘못된 것은 _function(부분)입니다.왜냐하면 이것은 함수가 아니라 함수이기 때문입니다.코드를 시험해 볼 수 있는 프리뷰를 소개합니다.

결론

절대값보다 duck-filter로 이동하는 경우 객체가 함수인지 확인하기 위해 callable(obj)을 사용하는 것이 좋습니다.

커스텀 is_function(obj)입니다.콜 가능한 클래스 인스턴스를 함수로 카운트하지 않고 함수가 내장되어 있거나 lamda, def 또는 partial로 정의되어 있는 경우 오브젝트가 함수인지 여부를 체크하기 위해 권장되는 방법이 될 수 있습니다.

이제 다 끝난 것 같아요.좋은 하루 보내세요!

그 밖에도 몇 가지 방법이 있습니다.

def isFunction1(f) :
    return type(f) == type(lambda x: x);

def isFunction2(f) :
    return 'function' in str(type(f));

두 번째 방법은 다음과 같습니다.

>>> type(lambda x: x);
<type 'function'>
>>> str(type(lambda x: x));
"<type 'function'>"
# Look Maa, function! ... I ACTUALLY told my mom about this!

'함수'가 입니다.__call__은 할 수 있습니다.

hasattr(obj, '__call__')

예를 들어 다음과 같습니다.

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

>>> x = 2
>>> hasattr(x, '__call__')
False

이것이 "최적의" 방법이지만, 콜 가능 여부 또는 메모 여부를 알아야 하는 이유에 따라 테스트/실행 블록에 넣을 수 있습니다.

try:
    x()
except TypeError:
    print "was not callable"

/제외보다 if hasattr(x, '__call__'): x() 때...라고 말할 수 있다.hasattr는, 해 타입 에러를 하는 일이 에, 보다합니다.를 들어 다음과 같습니다.TypeError는 잘못 검출되지 않습니다.

>>> def x():
...     raise TypeError
... 
>>> hasattr(x, '__call__')
True # Correct
>>> try:
...     x()
... except TypeError:
...     print "x was not callable"
... 
x was not callable # Wrong!

「 」를 에, 「 」를 체크합니다.'__call__') 여부를 확인할 수 func_name,func_doc 등에서는 통하지 않습니다.

>>> def x(): pass
... 
>>> hasattr(x, 'func_name')
True

하나의 확인 은 '보다 낫다'를 사용하는 입니다.isfunction()inspect★★★★★★ 。

>>> import inspect
>>> inspect.isfunction(x)
True

하려면 , 「메서드」를 합니다.inspect.ismethod()

에도 '아예'가 있기 __call__다른 방법을 권장합니다.

class A(object):
    def __init__(self):
        pass
    def __call__(self):
        print 'I am a Class'

MyClass = A()

def foo():
    pass

print hasattr(foo.__class__, 'func_name') # Returns True
print hasattr(A.__class__, 'func_name')   # Returns False as expected

print hasattr(foo, '__call__') # Returns True
print hasattr(A, '__call__')   # (!) Returns True while it is not a function

Python 클래스도 호출 가능합니다.

함수(및 표준 함수 및 람다)를 얻으려면 다음을 사용합니다.

import types

def is_func(obj):
    return isinstance(obj, (types.FunctionType, types.LambdaType))


def f(x):
    return x


assert is_func(f)
assert is_func(lambda x: x)

모든 함수가 클래스이므로 인스턴스 x의 클래스 이름을 가져와 비교할 수 있습니다.


if(x.__class__.__name__ == 'function'):
     print "it's a function"

「 」를 사용한 hasattr(obj, '__call__') ★★★★★★★★★★★★★★★★★」callable(.)단점이 : 둘 다 한다: 둘 다 반환한다.True및 인스턴스의 " " " "를 클래스 및 "를 가진 __call__()를 들면.

>>> import collections
>>> Test = collections.namedtuple('Test', [])
>>> callable(Test)
True
>>> hasattr(Test, '__call__')
True

함수 그도 없음)인지 여부를 중 는 " "를 하는 것입니다.isfunction(.):

>>> import inspect
>>> inspect.isfunction(Test)
False
>>> def t(): pass
>>> inspect.isfunction(t)
True

다른 타입을 체크할 필요가 있는 경우는 inspect - inspect live objects참조해 주세요.

에서 Python3가 .type (f) == type (lambda x:x)그 결과Truef와 ""입니다.False그렇지 않다면. 는 ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★isinstance (f, types.FunctionType)즉, 애드혹이 적은 것 같습니다.는 ★★★★★★★★★★★★★★★★★★★★를 하고 싶었다.type (f) is function근데 안 되네.

다음과 같이 시도해 볼 수 있습니다.

if obj.__class__.__name__ in ['function', 'builtin_function_or_method']:
    print('probably a function')

더 기괴한 것도 있어요

if "function" in lower(obj.__class__.__name__):
    print('probably a function')

@Sumukh Barve, @Katsu 및 @tinnick의 답변을 조합하여 콘솔에서 폐기할 수 있는 임베디드 기능 목록을 가져오는 경우 다음 두 가지 옵션을 사용할 수 있습니다.

  1. [i for i, j in __builtin__.__dict__.items() if j.__class__.__name__ in ['function', 'builtin_function_or_method']]
  2. [i for i, j in __builtin__.__dict__.items() if str(j)[:18] == '<built-in function']

이전의 회답에 따라서, 다음과 같은 것을 생각해 냈습니다.

from pprint import pprint

def print_callables_of(obj):
    li = []
    for name in dir(obj):
        attr = getattr(obj, name)
        if hasattr(attr, '__call__'):
            li.append(name)
    pprint(li)

제 코드입니다.

# -*- coding: utf-8 -*-
import hashlib
import inspect

# calc everything to md5!!
def count_md5(content):
    if isinstance(content, dict):
        return count_md5(
            [(str(k), count_md5(content[k])) for k in sorted(content.keys())],
        )
    elif isinstance(content, (list, tuple)):
        content = [count_md5(k) for k in content]
    elif callable(content):
        return make_callable_hash(content)
    return calc_md5(str(content))


def calc_md5(content):
    m2 = hashlib.md5()
    if isinstance(content, str):
        m2.update(content.encode("utf8"))
    else:
        m2.update(content)
    return m2.hexdigest()


def make_callable_hash(content):
    if inspect.isclass(content):
        h = []
        for attr in [i for i in sorted(dir(content)) if not i.startswith("__")]:
            v = getattr(content, attr)
            h.append(count_md5(v))

        return calc_md5("".join(h))

    return calc_md5(content.__name__)

가능의 경우, 의 경우, 의 값이하고 있는지 만으로, 「Attribute」의 할 수 .아트리뷰트callable평가해 주세요.callable은 클래스일 경우 true로 반환되므로 그다지 엄격하지 않습니다.

이 콜하여 캐치하기만 하면 .TypeError.

def myfunc(x):
  try:
    x()
  except TypeError:
    raise Exception("Not callable")

그것을 확인할 수 있는 「반복 방법」은 다음과 같습니다.람다와도 잘 어울려요.

def a():pass
type(a) #<class 'function'>
str(type(a))=="<class 'function'>" #True

b = lambda x:x*2
str(type(b))=="<class 'function'>" #True

아래 Python에 내장된 함수인 isinstance()와 type()를 사용하면 함수인지 확인할 수 있으므로 아무것도 Import할 필요가 없습니다.

def test():
    pass

print(isinstance(test, type(test)))

출력:

True

이것으로 충분합니다.

str(type(a))=="<class 'function'>"

입력이 문자열이 아닌지 확인하고 입력이 문자열에 캐스트되면 일치하는 이름이 반환되는 짧은 함수를 DIY로 지정할 수 있습니다.정의:

def isFunction(o):return not isinstance(o,str) and str(o)[:3]=='<fu';

이 코드는 이미 Python 버전 전체에 호환성이 있다고 생각합니다.

또는 변경사항이 있을 경우 소문자에 변환을 추가하고 내용 길이를 확인할 수 있습니다.표시된 함수의 형식 문자열은 "< function " + name + at 0xFFFFFF >" 입니다.

언급URL : https://stackoverflow.com/questions/624926/how-do-i-detect-whether-a-variable-is-a-function

반응형