メタクラスが何であるかが明確になったので、実際の意味を知らずに常に使用している関連概念があります。
誰もが一度は括弧を間違えて、「オブジェクトは呼び出し可能ではありません」という例外が発生したと思います。さらに、この血まみれが何に使われるのか疑問に思うように使用__init__
してください。__new__
__call__
マジックメソッドの例を含めて、いくつか説明していただけますか?
メタクラスが何であるかが明確になったので、実際の意味を知らずに常に使用している関連概念があります。
誰もが一度は括弧を間違えて、「オブジェクトは呼び出し可能ではありません」という例外が発生したと思います。さらに、この血まみれが何に使われるのか疑問に思うように使用__init__
してください。__new__
__call__
マジックメソッドの例を含めて、いくつか説明していただけますか?
callable とは、呼び出すことができるものすべてです。
組み込みのcallable ( objects.c の PyCallable_Check)は、引数が次のいずれかであるかどうかをチェックします。
__call__
または名前が付けられたメソッド__call__
は(ドキュメントによると)
インスタンスが関数として「呼び出された」ときに呼び出されます
class Foo:
def __call__(self):
print 'called'
foo_instance = Foo()
foo_instance() #this is calling the __call__ method
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
フィールドのtp_call
説明:
ternaryfunc tp_call
オブジェクトの呼び出しを実装する関数へのオプションのポインター。オブジェクトが呼び出せない場合、これはNULLである必要があります。署名はPyObject_Call()の場合と同じです。このフィールドはサブタイプに継承されます。
組み込み関数をいつでも使用して、callable
特定のオブジェクトが呼び出し可能かどうかを判断できます。またはそれでも、それを呼び出してTypeError
後でキャッチするだけです。callable
Python3.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')
呼び出し可能オブジェクトは、関数と同じように、丸括弧()を使用して、最終的にいくつかのパラメーターを渡すことができるオブジェクトです。
関数を定義するたびに、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)
これが、Pythonにない理由でもあります。foo = new int
クラスオブジェクトにそのインスタンスを返すようにするだけです__call__
。Pythonがこれを解決する方法は、私の意見では非常にエレガントです。
__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
>>>
__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)
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
これは、「(args)」を後に置いて、機能することを期待できるものです。callable は通常、メソッドまたはクラスです。メソッドが呼び出され、クラスがインスタンス化されます。
クラスの関数またはメソッドが呼び出し可能かどうかを確認するには、その関数を呼び出すことができることを意味します。
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
__call__
callables は特別なメソッドを実装するため、そのようなメソッドを持つオブジェクトはすべて呼び出し可能です。