Résultat
abrufbar(x)
hasattr(x, '__call__')
inspect.isfunction(x)
inspect.ismethod(x)
inspect.isgeneratorfunction(x)
inspect.iscoroutinefunction(x)
inspect.isasyncgenfunction(x)
isinstance(x, typing.Callable)
isinstance(x, types.BuiltinFunctionType)
isinstance(x, types.BuiltinMethodType)
isinstance(x, types.FunctionType)
isinstance(x, types.MethodType)
isinstance(x, types.LambdaType)
isinstance(x, functools.partial)
drucken
×
×
×
×
×
×
×
×
×
func
×
×
×
×
×
×
×
×
functools.partial
×
×
×
×
×
×
×
×
×
×
<lambda>
×
×
×
×
×
×
×
×
Generator
×
×
×
×
×
×
×
async_func
×
×
×
×
×
×
×
asynchroner_generator
×
×
×
×
×
×
×
A
×
×
×
×
×
×
×
×
×
×
×
func1
×
×
×
×
×
×
×
×
func2
×
×
×
×
×
×
×
×
×
func3
×
×
×
×
×
×
×
×
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 func1(self, a, b):
pass
@classmethod
def func2(cls, a, b):
pass
@staticmethod
def func3(a, b):
pass
for func in [print,
func,
partial,
_lambda,
generator,
async_func,
async_generator,
A,
A.func1,
A.func2,
A.func3]:
judge(func)
Zeit
Wählen Sie die drei gängigsten Methoden
Zeit/s
abrufbar(x)
0.86
hasattr(x, '__call__')
1.36
isinstance(x, typing.Callable)
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
61 Stimmen
Ich bin deprimiert über die Anzahl der Antworten, die das Problem umgehen, indem sie nach einigen aufrufen Attribut oder aufrufbare Funktion... Ein sauberer Weg ist über type(a) == types.functionType wie von @ryan vorgeschlagen
65 Stimmen
@AsTeR Die richtige Art und Weise, die Eigenschaften von Objekten mit dem Typ "Ente" zu prüfen, besteht darin, sie zu fragen, ob sie quaken, und nicht zu sehen, ob sie in einen Behälter in Entengröße passen. Der Ansatz "direkt vergleichen" wird für viele Funktionen, wie z.B. Builtins, die falsche Antwort geben.
5 Stimmen
@JohnFeminella Ich stimme Ihnen zwar im Prinzip zu. Der OP hat nicht gefragt, ob es aufrufbar ist, sondern nur, ob es eine Funktion ist. Vielleicht könnte man argumentieren, dass er eine Unterscheidung zwischen z.B. Funktionen und Klassen benötigt?
11 Stimmen
@AsTeR Es ist types.FunctionType, mit einem großen F.
0 Stimmen
@BenMares Ich kann nicht mehr editieren, aber danke, dass du es bemerkt hast!
0 Stimmen
@AsTeR Yeep saubere Art und Weise, aber das hängt irgendwie von der Person ab, die im Internet liest, ihre Entscheidung :) froh, dass Ryan es angesprochen hat.
3 Stimmen
使用方法
inspect.isfunction(object)
das im Modul inspect vorhanden ist.