Python変数が関数であるかどうかをどのように検出しますか?


686

変数がありますx。関数を指しているのかどうかを知りたいのですが。

私は次のようなことができることを望んでいました:

>>> isinstance(x, function)

しかし、それは私に与えます:

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

私が選んだ理由は

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

37
いくつかの呼び出し属性または呼び出し可能関数を探すことによって問題を回避する多くの答えに落ち込んでいます... @ryanによって示唆されているように、きれいな方法はtype(a)== types.functionTypeについてです
AsTeR

44
@AsTeRアヒル型のオブジェクトのプロパティをチェックする適切な方法は、カモのサイズのコンテナに収まるかどうかを確認するのではなく、ガチャガチャ音をたてるかどうかを尋ねることです。「直接比較する」アプローチは、組み込み関数のような多くの関数に対して誤った答えを与えます。
John Feminella、2014年

3
@JohnFeminella原則として同意します。OPは、それが関数であるかどうかだけで、呼び出し可能かどうかを尋ねませんでした。たぶん、彼は例えば関数とクラスの区別が必要だったと主張することができるでしょうか?
マッケイ

3
私の目的はinsepct.getsource、さまざまなオブジェクトで使用したかったためにここに来ました。実際には、オブジェクトが呼び出し可能かどうかではなく、に「機能」を与えるものかどうかが重要ですtype(obj)。グーグルが私をここに導いたので、AsTeRのコメントが(私にとって)最も有用な答えだったと思います。インターネット上には、人々が発見し__call__たり発見したりできる場所がたくさんありますcallable
tsbertalan

4
@AsTeRそれは資本F.とtypes.FunctionType、ある
ベン・マレス

回答:


891

これが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関数とは何かについて非常に具体的な考えがない限り、使用しないでください。


73
これは、それが関数であるかどうか、つまり、呼び出すことができるかどうかは通知しません。
クリスB.

23
区別が重要かどうかは、アプリケーションによって異なります。元の質問には当てはまらないのは正しいと思いますが、それは確かではありません。
クリスB.

5
クラスには、呼び出し関数を関連付けることができます。したがって、これは間違いなく区別するための良い方法ではありません。ライアンの方法が優れています。
Brian Bruggeman、2011

43
「ダックタイピング」の概念は、これをより良い答えにします。たとえば、「関数が1つのように動作する限り、それが関数である場合、それはどういうことですか?」
jcomeau_ictx 2012年

8
たとえば、デコレータを書くときなど、呼び出し可能関数と関数の区別が重要なユースケースがあります(ライアンの回答に関する私のコメントを参照)。
Turion、

267

組み込みの名前空間にコンストラクターを持たない組み込み型(関数、ジェネレーター、メソッドなど)は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


5
質問に答える+1。ただし、オブジェクトが関数であるかどうか、またはそれが呼び出し可能なオブジェクトであるかどうかを推測することは、通常は間違いです。OPからの詳細な情報がないと、もちろん
手放せ

47
組み込み関数に対しては、実際にはFalseを返します。具体的には、isinstance(f、(types.FunctionType、types.BuiltinFunctionType))を使用する必要があります。もちろん、呼び出し可能オブジェクトやメソッドではなく、関数だけが厳密に必要な場合は。
Lukasz Korzybski

5
@ŁukaszKorzybskiともっと正確に... functools.partialをチェックする必要があります:isinstance(f, (types.FunctionType, types.BuiltinFunctionType, functools.partial))またはf.funcそのような場合にチェックします。
estani 2013年

3
@bobince、このユースケースはどうですか:@fooas @fooとasの両方を使用できるデコレーターを書きたいと思い@foo(some_parameter)ます。次に、それが呼び出されているものを確認する必要があります。たとえば、装飾する関数(最初のケース)やパラメーター(2番目のケース。追加のデコレーターを返す必要がある場合)です。
Turion、

types.BuiltinFunctionType(「通常の」)組み込みメソッドのタイプでもありますcallable。ルートを使用しない場合は、これを許可したくない場合があります。
user2357112は18:12にMonica

92

Python 2.1以降でisfunctionは、inspectモジュールからインポートできます。

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

3
素敵ですが、openおよびなどの組み込み関数に対してはFalseを返すようhasattrです。
Zecc、2013年

12
@Zecc isbuiltinはそのためです。
Paolo 2013

13
inspect.isfunctiondocstringを参照してください:「オブジェクトがユーザー定義関数の場合はtrueを返します。」
マークミコフスキー2013

4
'isfunction'はfunctool.partial関数を認識しないことに注意してください。
ishmael

74

受け入れられた回答は、提供された時点で正しいと考えられていたものです。結局のところ、存在しない勝るためにcallable()具体的には、:バックのPython 3.2であり、callable()チェックtp_call対象のフィールドがテストされては。同等の単純なPythonはありません。ほとんどの場合、推奨されるテストは正しいものです。

>>> 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()


5
hasattr(o, '__call__')アプローチの落とし穴の驚くべきイラストと、callable()可能な場合はなぜ優れているのか。
MestreLion、2015年

39

以下はブール値を返します:

callable(x)

1
それで彼の問題は解決しますが、彼はまだ謎を作り出しました:xがモジュールbuiltinのクラス 'function'であり、help(x .__ class__)が「クラス関数」を記述している場合、なぜ「関数」は明らかに「定義されていない」のですか?
ケン

1
「関数」はキーワードでも組み込み型でもありません。関数のタイプは、「types」モジュールで「types.FunctionType」として定義されています
Chris B.


19

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はわかりませんが、実行時にaをスローするか、そもそも呼び出し可能ではありません。それはあなたにとって重要ではないかもしれません。


8
それを呼ぶのは悪い考えです。それが副作用を持っている場合、または実際に何かをするが本当に時間がかかる場合はどうなりますか?
asmeurer 2013年

@asmeurer-呼び出していないのに関数であるかどうかを知る必要があるのはなぜですか。
2013

1
@detly:デバッグのために定期的にオブジェクト内のすべての変数を出力したいのですが、メソッドは通常私には役に立たないため、実行したくありません。最後に、すべての呼び出し不可のプロパティと対応する値をリストします:)
Wolph

2
呼び出していないからといって、呼び出されていないわけではありません。たぶんあなたは派遣をしている。
asmeurer 2013

4
呼び出し可能かどうかを知るために例外を使用することには大きな問題があります。それ呼び出し可能であるが、それを呼び出すと、探している例外が発生する場合はどうなりますか?エラー無視して無視することも、呼び出し可能かどうか誤診することもできます。EAFPを使用しているときは、実際にやりすぎないようにしたいのですが、この使用例ではそれを行う方法はありません。
ベン

15

構文的に関数のように見えるすべてのものを検出したい場合:関数、メソッド、組み込みのfun / meth、lambda ...ですが呼び出し可能なオブジェクト(__call__メソッドが定義されたオブジェクト)を除外してから、次のものを試してください:

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

これをモジュールのis*()チェックのコードと比較しましたinspect。特に、目的が関数のフィルタリングまたはオブジェクトの通常のプロパティの検出である場合、上記の式ははるかに完全です。


typesモジュールを紹介していただきありがとうございます。make_stemmer()場合によっては関数を返し、場合によっては呼び出し可能なStemmerインスタンスを返すファクトリをテストしていて、その違いを検出する必要がありました。
ホブ、2016年


6

あなたが学んだC++なら、あなたはに精通している必要がありますfunction objectまたはfunctor、できるすべてのオブジェクトを意味しますbe called as if it is a function

C ++では、 an ordinary functionは関数オブジェクトであり、関数ポインターも同様です。より一般的には、を定義するクラスのオブジェクトも同様operator()です。C ++ 11以降the lambda expressionの場合functorもそうです。

類似点は、Pythonではこれらfunctorsすべてcallableです。An 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]
"""

ファンクターのタイプ(types.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

6

受け入れられた回答として、ジョンフェミネラは次のように述べています。

アヒル型のオブジェクトのプロパティをチェックする適切な方法は、カモの大きさのコンテナに収まるかどうかを確認するのではなく、ガチャガチャ音をたてるかどうかを尋ねることです。「直接比較する」アプローチは、組み込み関数のような多くの関数に対して誤った答えを与えます。

関数を厳密に区別するために2つのライブラリーがありますが、徹底的に比較可能な表を描画します。

8.9。型—動的型の作成と組み込み型の名前— Python 3.7.0ドキュメント

30.13。inspect —ライブオブジェクトの検査— 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

もう1つのステップで組み込み関数またはユーザー定義関数かどうかを確認するとき

#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ます。


5

関数は単なる__call__メソッドを持つクラスなので、次のことができます

hasattr(obj, '__call__')

例えば:

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

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

これが「最良の」方法ですが、呼び出し可能かメモかを知る必要がある理由によっては、try / execptブロックに入れるだけです。

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

try / exceptが行うよりもPythonであるかどうかは議論の余地があり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!

例外処理を使用して、予期しない動作のみを保護し、ロジックフローを保護しないでください。これは、Pythonicではありません。
gotgenes 2009年

まあ、hasattrは基本的にはtry / exceptブロックでgetattrを実行します(ただしCでは)。blog.jancewicz.net/2007/10/reflection-hasattr.html
dbr

@dbr:しかし、hasattrはより美的です。
Nikhil Chelliah 2009年

5

他にいくつかの方法があります:

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

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

ここに私が2番目を思いついた方法があります:

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

これはいいね!python2.xとpython3.xのすべてのバージョンで動作するはずです!
Saurav Kumar

4

代わりをチェックする'__call__'(機能への排他的ではありません)、ユーザー定義関数が属性を持っているかどうかチェックすることができfunc_namefunc_docなど、これは方法のために動作しません。

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

チェックの別のisfunction()方法は、inspectモジュールのメソッドを使用することです。

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

オブジェクトがメソッドかどうかを確認するには、次を使用します inspect.ismethod()


4

クラスにも__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

1
ジョンフェミネラの回答hasattr(obj, '__call__')はあいまいです。
GoingMyWay 2016

4

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)

2

どの関数もクラスなので、インスタンスxのクラスの名前を取得して比較できます。


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

2

いくつかの回答を使用hasattr(obj, '__call__')してcallable(.)言及されているソリューションには、主な欠点があります。どちらもTrue、クラスと、__call__()メソッドを含むクラスのインスタンスに戻ります。例えば。

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

オブジェクトがユーザー定義関数(およびそれ以外のもの)かどうかを確認する適切な方法の1つは、次のものを使用することisfunction(.)です。

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

他のタイプを確認する必要がある場合は、inspect — Inspect live objectsをご覧ください。


2

正確な関数チェッカー

callableは非常に優れたソリューションです。しかし、私はこれをジョンフェミネラとは逆の方法で扱いたかったのです。このように扱う代わりに:

アヒル型のオブジェクトのプロパティをチェックする適切な方法は、カモの大きさのコンテナに収まるかどうかを確認するのではなく、ガチャガチャ音をたてるかどうかを尋ねることです。「直接比較する」アプローチは、組み込み関数のような多くの関数に対して誤った答えを与えます。

これを次のように扱います。

何かがアヒルであるかどうかを確認する適切な方法は、それがガタガタできるかどうかを確認することではなく、表面からアヒルのように見えるかどうかだけを確認するのではなく、実際にいくつかのフィルターを介してアヒルであるかどうかを確認することです。

どのように実装するか

「タイプ」モジュールは機能を検出するためのクラスをたくさん持っている、最も有用であるのtypes.FunctionType、メソッドタイプ、組み込みタイプ、ラムダタイプなど、他にもたくさんあります。また、「functools.partial」オブジェクトを関数と見なします。

関数かどうかを確認する簡単な方法は、これらすべての型にisinstance条件を使用することです。以前は、上記のすべてから継承する基本クラスを作成したかったのですが、Pythonでは上記のクラスの一部からの継承が許可されていないため、これを行うことはできません。

次の表は、どのクラスがどの機能を分類できるかを示しています。

kinght-金の関数表 kinght-金による上記の関数表

それを行うコード

これが、上で説明したすべての作業を行うコードです。

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]

is_function(partial)はfalseでした。これは関数ではなくクラスであり、これはクラスではなく関数です。こちらがプレビューです、コードを試すためです。

結論

callable(obj)は、絶対オブジェクトをダックタイピングして移動したい場合に、オブジェクトが関数かどうかを確認するための推奨メソッドです

カスタムis_function(obj)、おそらくいくつかの編集は、関数としてカウント可能な呼び出し可能なクラスインスタンスがなく、組み込み関数、またはlambdadef、または部分的

そして、それですべてが終わりだと思います。良い一日を過ごしてください!


1

python3では私が思い付いtype (f) == type (lambda x:x)た利回りTrue場合はf関数であり、Falseそうでない場合。しかし、私はを好むと思いますisinstance (f, types.FunctionType)。やりたかったのですtype (f) is functionが、うまくいきません。


0

以前の返信に続き、私はこれを思いつきました:

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)

0

あなたはこれを試すことができます:

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')

-1

値が呼び出し可能である場合にコードが呼び出しを実行する場合は、呼び出しを実行してcatchしTypeErrorます。

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

4
これは危険です。あなたにはどんな副作用xがあるのか分かりません。
cwallenpoole 2017年

-2

以下は、それをチェックするための「repr方法」です。また、ラムダでも動作します。

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

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

-3

これは私にとってはうまくいきます:

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

1
そして、結果が空の文字列である場合、それは私たちに何を伝えますか?関数の場合、私はを取得"<type 'function'>"し、整数の場合、私はを取得します"<type 'int'>"。したがって、それがどのように機能するかはわかりません:/
pawamoy

今はPython 3でのみ機能します:)また、質問の元の意図によっては、不完全です:組み込み関数は関数openと見なされますか?Python 3でstr(type(open))与える<class 'builtin_function_or_method'>
pawamoy
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.