345

メタクラスが何であるかが明確になったので、実際の意味を知らずに常に使用している関連概念があります。

誰もが一度は括弧を間違えて、「オブジェクトは呼び出し可能ではありません」という例外が発生したと思います。さらに、この血まみれが何に使われるのか疑問に思うように使用__init__してください。__new____call__

マジックメソッドの例を含めて、いくつか説明していただけますか?

4

12 に答える 12

340

callable とは、呼び出すことができるものすべてです。

組み込みのcallable ( objects.c の PyCallable_Check)は、引数が次のいずれかであるかどうかをチェックします。

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

名前が付けられたメソッド__call__は(ドキュメントによると

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

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

foo_instance = Foo()
foo_instance() #this is calling the __call__ method
于 2008-09-21T15:44:22.697 に答える
91

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

フィールドのtp_call説明

ternaryfunc tp_callオブジェクトの呼び出しを実装する関数へのオプションのポインター。オブジェクトが呼び出せない場合、これはNULLである必要があります。署名はPyObject_Call()の場合と同じです。このフィールドはサブタイプに継承されます。

組み込み関数をいつでも使用して、callable特定のオブジェクトが呼び出し可能かどうかを判断できます。またはそれでも、それを呼び出してTypeError後でキャッチするだけです。callablePython3.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')
于 2008-09-22T15:04:53.733 に答える
43

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

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

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

func = a()

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

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

于 2008-09-26T13:22:20.393 に答える
39

逆に説明させてください:

このことを考慮...

foo()

...の構文糖衣として:

foo.__call__()

fooに応答するオブジェクトはどこにありますか__call__。私がオブジェクトと言うとき、それはそれを意味します:組み込み型、あなた自身のクラスとそれらのインスタンス。

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

int('10')
unicode(10)

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

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

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

于 2013-03-22T23:38:33.647 に答える
11

__call__Callable はメソッドを持つオブジェクトです。これは、呼び出し可能な関数を偽造したり、関数を取得してそれを強化するものを追加したり、いくつかのパラメーターを埋めたりして、順番に呼び出すことができるものを返す (関数型プログラミング界ではカリー化として知られている)部分関数アプリケーションのような巧妙なことを行うことができることを意味します。 )。

特定のタイポグラフィ エラーにより、インタープリターは、(たとえば) 文字列など、意図しないものを呼び出そうとします。これにより、インタープリターが呼び出し不可能なアプリケーションを実行しようとすると、エラーが発生する可能性があります。以下のトランスクリプトのようなことを行うことで、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
>>> 
于 2008-09-21T15:43:15.880 に答える
10

__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)
于 2008-09-21T15:49:28.953 に答える
7

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

于 2008-09-21T15:43:20.840 に答える
6

Python では、callable は__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
于 2008-09-21T16:37:09.307 に答える
3

これは、「(args)」を後に置いて、機能することを期待できるものです。callable は通常、メソッドまたはクラスです。メソッドが呼び出され、クラスがインスタンス化されます。

于 2008-09-21T15:43:44.960 に答える
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
于 2016-09-20T10:03:37.330 に答える
2

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

于 2012-05-07T21:40:12.383 に答える