メタクラスが何であるかが明らかになったので、それが本当に何を意味するのかを知らずに常に使用するという関連する概念があります。
かっこで間違いを犯した人は誰でもいるので、「オブジェクトは呼び出し不可能」という例外が発生したと思います。さらに、使用して__init__
、__new__
この流血__call__
が何に使用できるのか不思議につながります。
魔法の方法の例を含め、いくつかの説明をお願いします。
メタクラスが何であるかが明らかになったので、それが本当に何を意味するのかを知らずに常に使用するという関連する概念があります。
かっこで間違いを犯した人は誰でもいるので、「オブジェクトは呼び出し不可能」という例外が発生したと思います。さらに、使用して__init__
、__new__
この流血__call__
が何に使用できるのか不思議につながります。
魔法の方法の例を含め、いくつかの説明をお願いします。
回答:
呼び出し可能オブジェクトは、呼び出すことができるすべてのものです。
内蔵の呼び出し可能(objects.cでPyCallable_Check)のチェックは、引数のいずれかの場合:
__call__
メソッドを持つクラスのインスタンスまたは名前付きのメソッド__call__
は(ドキュメントによると)
インスタンスが関数として「呼び出された」ときに呼び出されます
class Foo:
def __call__(self):
print 'called'
foo_instance = Foo()
foo_instance() #this is calling the __call__ method
callable
実際に何かが呼び出し可能かどうかを通知しますが、チェックを行う__call__
と何も通知されません。オブジェクトは、場合o
提供__getattribute__
や__getattr__
、hasattr(o, '__call__')
真を返すことがあり、まだo
Pythonはスキップするので、まだ呼び出し可能ではないだろう__getattribute__
と__getattr__
の通話のために。したがって、呼び出し可能かどうかを確認するために残された唯一の実際の方法は、EAFPです。
callable()
、Python 3.xのドキュメントを参照してください:「この関数は、最初にPython 3.0で削除され、次にPython 3.2に戻されました。」
tp_call
確認のみが行われているようです。PyCallable_Checkの実装を参照してください。3行です。
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;
}
}
それは言う:
__call__
です。x
は呼び出し可能な場合に限り x->ob_type->tp_call != NULL
Desciption tp_call
分野:
ternaryfunc tp_call
オブジェクトの呼び出しを実装する関数へのオプションのポインター。オブジェクトが呼び出し可能でない場合、これはNULLでなければなりません。シグネチャはPyObject_Call()と同じです。このフィールドはサブタイプによって継承されます。
常に組み込みcallable
関数を使用して、指定したオブジェクトが呼び出し可能かどうかを判別できます。またはより良いまだそれを呼び出してTypeError
後でキャッチします。callable
Python 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')
def f(): ...
、クラスのようなオブジェクトclass C: ...
、すなわちf
、''.strip
、len
、およびC
すべての呼び出し可能です。__call__()
クラスにメソッドを持つインスタンスは比較的まれです。
呼び出し可能オブジェクトは、丸括弧()を使用して、最終的には関数のようにいくつかのパラメーターを渡すことができるオブジェクトです。
関数を定義するたびに、Pythonは呼び出し可能なオブジェクトを作成します。たとえば、関数funcを次のように定義できます(同じです)。
class a(object):
def __call__(self, *args):
print 'Hello'
func = a()
# or ...
def func(*args):
print 'Hello'
doitやrunなどのメソッドの代わりにこのメソッドを使用することもできます。obj.doit()よりもobj()の方がわかりやすいと思います。
逆に説明しましょう:
このことを考慮...
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は、インスタンスではなく、常にクラスで呼び出されます。また、メタクラスも通過しません。ほとんどの場合、それは単なるひっくり返しですが、それは時には重要です。
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
>>>
簡単に言うと、「呼び出し可能」はメソッドのように呼び出すことができるものです。組み込み関数「callable()」は、呼び出しプロパティのチェックと同様に、何かが呼び出し可能に見えるかどうかを通知します。関数はクラスと同様に呼び出し可能であり、クラスインスタンスは呼び出し可能です。この詳細については、こちらとこちらをご覧ください。
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
クラスの関数またはメソッドが呼び出し可能であるかどうかを確認することは、その関数を呼び出すことができることを意味します。
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
callable(obj.__init___)
(AttributeErrorのように)余分なアンダースコアがないのは確かですか?そうでない場合、答えはその答えではないのTrue
ですか?
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
>>>
ありがとうございました。よろしく、マリス
print
関数を呼び出すと、Pythonはタイプprintのオブジェクトを作成し、そのメソッドを呼び出します__call__
」。Pythonは印刷オブジェクトを作成しません。それはと同等のものを呼び出すだけtype(print).__call__(print, *args, **kwargs)
です。そして、最初の文はあまり意味がありません。呼び出し可能なオブジェクトと関数を「呼び出し可能」に混同しているようです。