「呼び出し可能」とは何ですか?


310

メタクラスが何であるかが明らかになったので、それが本当に何を意味するのかを知らずに常に使用するという関連する概念があります。

かっこで間違いを犯した人は誰でもいるので、「オブジェクトは呼び出し不可能」という例外が発生したと思います。さらに、使用して__init____new__この流血__call__が何に使用できるのか不思議につながります。

魔法の方法の例を含め、いくつかの説明をお願いします。


回答:


308

呼び出し可能オブジェクトは、呼び出すことができるすべてのものです。

内蔵の呼び出し可能(objects.cでPyCallable_Check)のチェックは、引数のいずれかの場合:

  • __call__メソッドを持つクラスのインスタンスまたは
  • ヌルでないtp_call(c struct)メンバーを持つ型であり、それ以外の場合(関数、メソッドなど)の呼び出し可能性を示します。

名前付きのメソッド__call__は(ドキュメントによると

インスタンスが関数として「呼び出された」ときに呼び出されます

class Foo:
  def __call__(self):
    print 'called'

foo_instance = Foo()
foo_instance() #this is calling the __call__ method

6
組み込みの呼び出し可能にするためにチェックするの賛成でPython 3.0で削除されていることに注意してくださいコール
イーライCourtwright

13
@エリ:うーん、非常に悪い動きのようですね。callable実際に何かが呼び出し可能かどうかを通知しますが、チェックを行う__call__と何も通知されません。オブジェクトは、場合o提供__getattribute____getattr__hasattr(o, '__call__')真を返すことがあり、まだoPythonはスキップするので、まだ呼び出し可能ではないだろう__getattribute____getattr__の通話のために。したがって、呼び出し可能かどうかを確認するために残された唯一の実際の方法は、EAFPです。
L̲̳o̲̳̳n̲̳̳g̲̳̳p̲̳o̲̳̳k̲̳̳e̲̳̳ 2010

49
@Longpoke:参考までにcallable()、Python 3.xのドキュメントを参照しください:「この関数は、最初にPython 3.0で削除され、次にPython 3.2に戻されました。
Tadeck 2013年

Python 3.8では存在のtp_call確認のみが行われているようです。PyCallable_Checkの実装を参照してください。3行です。
ミケーレピッコリーニ

84

Pythonのソースobject.cから

/* Test whether an object can be called */

int
PyCallable_Check(PyObject *x)
{
    if (x == NULL)
        return 0;
    if (PyInstance_Check(x)) {
        PyObject *call = PyObject_GetAttrString(x, "__call__");
        if (call == NULL) {
            PyErr_Clear();
            return 0;
        }
        /* Could test recursively but don't, for fear of endless
           recursion if some joker sets self.__call__ = self */
        Py_DECREF(call);
        return 1;
    }
    else {
        return x->ob_type->tp_call != NULL;
    }
}

それは言う:

  1. オブジェクトが何らかのクラスのインスタンスである場合、そのオブジェクトは属性を持っている限り呼び出し可能__call__です。
  2. そうでない場合、オブジェクトxは呼び出し可能な場合に限り x->ob_type->tp_call != NULL

Desciption tp_call分野

ternaryfunc tp_callオブジェクトの呼び出しを実装する関数へのオプションのポインター。オブジェクトが呼び出し可能でない場合、これはNULLでなければなりません。シグネチャはPyObject_Call()と同じです。このフィールドはサブタイプによって継承されます。

常に組み込みcallable関数を使用して、指定したオブジェクトが呼び出し可能かどうかを判別できます。またはより良いまだそれを呼び出してTypeError後でキャッチします。callablePython 3.0および3.1では削除されました。callable = lambda o: hasattr(o, '__call__')またはを使用してくださいisinstance(o, collections.Callable)

例、単純なキャッシュの実装:

class Cached:
    def __init__(self, function):
        self.function = function
        self.cache = {}

    def __call__(self, *args):
        try: return self.cache[args]
        except KeyError:
            ret = self.cache[args] = self.function(*args)
            return ret    

使用法:

@Cached
def ack(x, y):
    return ack(x-1, ack(x, y-1)) if x*y else (x + y + 1) 

標準ライブラリ、ファイルsite.py、組み込みexit()およびquit()関数の定義の例:

class Quitter(object):
    def __init__(self, name):
        self.name = name
    def __repr__(self):
        return 'Use %s() or %s to exit' % (self.name, eof)
    def __call__(self, code=None):
        # Shells like IDLE catch the SystemExit, but listen when their
        # stdin wrapper is closed.
        try:
            sys.stdin.close()
        except:
            pass
        raise SystemExit(code)
__builtin__.quit = Quitter('quit')
__builtin__.exit = Quitter('exit')

10
callメソッドの例は、キャッシュとデコレータのレシピと混同しているため、誤解を招く可能性が高いと思います。これは、call
FlorianBöschSep

3
JFセバスチャンは、他の場所からコピー&ペーストした最小限ではない例を重ねても役に立たない。
フロリアンボッシュ

20
@JF Sebastian:より現実的な例が優れているのはBSです。例として、泣かせてしまうような本物のようなコードを紹介します。簡単な例も機能し、気を散らさないため、何かを説明するのに適しています。
フロリアンボッシュ

5
呼び出し可能オブジェクトについて説明していますが、呼び出し可能オブジェクトを使用してデコレータを定義する方法の例を示しました。callableの典型的な使用法であることはわかっていますが、何がcallableで、どのようにcallableを使用するかを知りたいだけの読者を混乱させる可能性があります。@FlorianBöschの答えを選びます。
KFL 2012年

2
@Kay:@FlorianBöschの回答(現在の形式)も気に入っています。ところで、デコレータは「呼び出し可能」の典型的な使用法ではありません。最も典型的な「呼び出し可能オブジェクトは」のような機能/メソッドでdef f(): ...、クラスのようなオブジェクトclass C: ...、すなわちf''.striplen、およびCすべての呼び出し可能です。__call__()クラスにメソッドを持つインスタンスは比較的まれです。
jfs

37

呼び出し可能オブジェクトは、丸括弧()を使用して、最終的には関数のようにいくつかのパラメーターを渡すことができるオブジェクトです。

関数を定義するたびに、Pythonは呼び出し可能なオブジェクトを作成します。たとえば、関数funcを次のように定義できます(同じです)。

class a(object):
    def __call__(self, *args):
        print 'Hello'

func = a()

# or ... 
def func(*args):
    print 'Hello'

doitrunなどのメソッドの代わりにこのメソッドを使用することもできます。obj.doit()よりもobj()の方がわかりやすいと思います。


37

逆に説明しましょう:

このことを考慮...

foo()

...の構文糖として:

foo.__call__()

にはfoo、に応答するオブジェクトを指定できます__call__。オブジェクトとは、組み込み型、独自のクラス、およびそれらのインスタンスのことです。

組み込み型の場合、次のように記述します。

int('10')
unicode(10)

あなたは本質的にやっています:

int.__call__('10')
unicode.__call__(10)

それfoo = new intがPythonにない理由でもあります__call__。クラスオブジェクトにインスタンスを返すようにさせるだけです。Pythonがこれを解決する方法は、私の意見では非常にエレガントです。


あなたは本質的にやっているtype(int).__call__(int, '10')type(unicode).__call__(unicode, '10')。Dunderは、インスタンスではなく、常にクラスで呼び出されます。また、メタクラスも通過しません。ほとんどの場合、それは単なるひっくり返しですが、それは時には重要です。
マッド物理学者

11

Callableは、__call__メソッドを持つオブジェクトです。この手段することができます偽の呼び出し可能な関数などをきちんと行う部分関数アプリケーションあなたは機能やアドオン何かを取ることとして知られている順番(に呼び出すことができます増強することやパラメータの一部で塗りつぶし、何かを返すカリー化関数型プログラミングサークルで)。

特定のタイプミスでは、インタプリタが(たとえば)文字列など、意図していないものを呼び出そうとします。これにより、インタープリターが呼び出し不可のアプリケーションを実行しようとするとエラーが発生する可能性があります。以下のトランスクリプトのようなことを行うと、Pythonインタープリターでこれが起こっているのを確認できます。

[nigel@k9 ~]$ python
Python 2.5 (r25:51908, Nov  6 2007, 15:55:44) 
[GCC 4.1.2 20070925 (Red Hat 4.1.2-27)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> 'aaa'()    # <== Here we attempt to call a string.
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'str' object is not callable
>>> 

9

__call__ 任意のオブジェクトを関数として呼び出し可能にします。

この例では8が出力されます。

class Adder(object):
  def __init__(self, val):
    self.val = val

  def __call__(self, val):
    return self.val + val

func = Adder(5)
print func(3)

7

簡単に言うと、「呼び出し可能」はメソッドのように呼び出すことができるものです。組み込み関数「callable()」は、呼び出しプロパティのチェックと同様に、何かが呼び出し可能に見えるかどうかを通知します。関数はクラスと同様に呼び出し可能であり、クラスインスタンスは呼び出し可能です。この詳細については、こちらこちらをご覧ください


5

Pythonでは、呼び出し可能オブジェクトは、型が__call__メソッドを持つオブジェクトです。

>>> class Foo:
...  pass
... 
>>> class Bar(object):
...  pass
... 
>>> type(Foo).__call__(Foo)
<__main__.Foo instance at 0x711440>
>>> type(Bar).__call__(Bar)
<__main__.Bar object at 0x712110>
>>> def foo(bar):
...  return bar
... 
>>> type(foo).__call__(foo, 42)
42

それと同じくらい簡単です:)

もちろんこれはオーバーロードすることができます:

>>> class Foo(object):
...  def __call__(self):
...   return 42
... 
>>> f = Foo()
>>> f()
42

3

クラスの関数またはメソッドが呼び出し可能であるかどうかを確認することは、その関数を呼び出すことができることを意味します。

Class A:
    def __init__(self,val):
        self.val = val
    def bar(self):
        print "bar"

obj = A()      
callable(obj.bar)
True
callable(obj.__init___)
False
def foo(): return "s"
callable(foo)
True
callable(foo())
False

1
callable(obj.__init___)(AttributeErrorのように)余分なアンダースコアがないのは確かですか?そうでない場合、答えはその答えではないのTrueですか?
Mad Physicist

2

これは、「(args)」の後に置くことができ、機能することを期待できます。呼び出し可能オブジェクトは通常、メソッドまたはクラスです。メソッドが呼び出され、クラスがインスタンス化されます。


2

callableは__call__特別なメソッドを実装しているので、そのようなメソッドを持つオブジェクトはすべて呼び出し可能です。


__call__クラスがそのようなメソッドを定義していない場合、定義したインスタンスを呼び出すことはできません。
マッド

2

Callableは、メソッド呼び出しを伴う「組み込み関数またはメソッド」のタイプまたはクラスです。

>>> type(callable)
<class 'builtin_function_or_method'>
>>>

例: printは呼び出し可能なオブジェクトです。組み込み関数__call__を使用 する場合print関数を呼び出すと、Python はタイプprintのオブジェクトを作成し、そのメソッド__call__を呼び出して、パラメーターがあればそれを渡します。

>>> type(print)
<class 'builtin_function_or_method'>
>>> print.__call__(10)
10
>>> print(10)
10
>>>

ありがとうございました。よろしく、マリス


1
ここの情報の一部はまっすぐに間違っています。たとえば、「print関数を呼び出すと、Pythonはタイプprintのオブジェクトを作成し、そのメソッドを呼び出します__call__」。Pythonは印刷オブジェクトを作成しません。それはと同等のものを呼び出すだけtype(print).__call__(print, *args, **kwargs)です。そして、最初の文はあまり意味がありません。呼び出し可能なオブジェクトと関数を「呼び出し可能」に混同しているようです。
Mad Physicist
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.