私たちは、関数はオブジェクトでもあることを知っています。しかし、関数オブジェクトはどのように関数と比較されますか?関数オブジェクトと関数の違いは何ですか?関数オブジェクトによってPythonの "関数オブジェクト"は機能していますか?
私はそのように定義されグラムを意味:
class G(object):
def __call__(self, a):
pass
g = G()
機能では、私はこの意味:
def f(a):
pass
私たちは、関数はオブジェクトでもあることを知っています。しかし、関数オブジェクトはどのように関数と比較されますか?関数オブジェクトと関数の違いは何ですか?関数オブジェクトによってPythonの "関数オブジェクト"は機能していますか?
私はそのように定義されグラムを意味:
class G(object):
def __call__(self, a):
pass
g = G()
機能では、私はこの意味:
def f(a):
pass
あなたはDEFステートメントを使用するときPythonはあなたのための関数オブジェクトを作成し、または使用をラムダ式:
>>> def foo(): pass
...
>>> foo
<function foo at 0x106aafd70>
>>> lambda: None
<function <lambda> at 0x106d90668>
したがって、Pythonで関数を定義するときはいつでも、このようなオブジェクトが作成されます。 はありません。の機能定義方法はありません。
OPが彼の質問を明確にした後、これは無関係のようです。 –
'function'オブジェクトには属性 '__set__'がありますか?属性 '__get__'はどうですか?あなたは私の質問に答えていません。 – jimifiki
TLは、DR__call__
は例えば呼び出すことができます実装する任意のオブジェクト:機能、カスタムクラス、など。
少し長いバージョン:(すべて O Fトン内線ワット)
python仮想マシンの実装内に何があるのかという相違点についての完全な答えがあるので、私たちはそのフードの下でPythonを見ていかなければなりません。まず、コードオブジェクトの概念があります。 Pythonは、あなたがそれに投げるものをパースします。それは、バイトコードとして知られるすべてのプラットフォームで同じ内部言語です。これを視覚的に再現するのは、作成したカスタムライブラリをインポートした後に.pycファイルを取得する場合です。これらは、Python VMの生の指示です。これらの命令がソースコードからどのように作成されるのかを無視して、PyEval_EvalFrameEx
をPython/ceval.cで実行します。ソースコードは獣のビットですが、最終的には複雑なビットを抽象化した単純なプロセッサのように機能します。バイトコードは、このプロセッサのアセンブリ言語です。特に、この「プロセッサ」の「オペコード」の1つは、CALL_FUNCTION
です。コールバックは、最終的にPyObject_Call()
に到達するいくつかの呼び出しを経由します。この関数は、PyObject
へのポインタを取り、それのタイプからtp_call
属性を抽出し、それを直接呼び出す(それが最初だ場合、技術的に、それはチェック):__call__
を実装する任意のオブジェクトがポインタでtp_call
属性が付与され
...
call = func->ob_type->tp_call //func is an arg of PyObject_Call() and is a pointer to a PyObject
...
result = (*call)(func, arg, kw);
実際の関数に渡します。 CPythonの実装で定義され、それはPythonのVMがのためにバイトコードの実行を開始すべき方法を定義している機能のため
FLSLOT("__call__", tp_call, slot_tp_call, (wrapperfunc)wrap_call,
"__call__($self, /, *args, **kwargs)\n--\n\nCall self as a function.",
PyWrapperFlag_KEYWORDS)
__call__
方法自体:私はそれをオブジェクト/ typeobject.cからslotdefs[]
difinitionによって処理されると信じその関数とデータが返される方法(存在する場合)任意のクラスに__call__
メソッドを渡すと、その属性は関数オブジェクトであり、再び__call__
のcpython実装を参照します。したがって、「通常の」関数を呼び出すときは、foo.__call__
が参照されます。呼び出し可能なクラスを呼び出すと、self.__call__
はfoo
に相当し、呼び出される実際のcpython参照はself.__call__.im_func.__call__
です。
免責事項
これは私のために多少未知の水域への旅であったが、それは私が実装の細かい点の一部を誤って伝えてきたことは完全に可能です。私は主にthisからpython callablesがどのように動作しているか、そしてpythonを通して私自身のものを掘り下げたブログ記事を取得しました。
お返事ありがとうございました。実際には、なぜ、 'function'オブジェクトに属性 '__set__'と '__get__'がないのかといった、高水準言語の機能についてもっと疑問に思っていました。しかし、あなたの答えにあなたが提供した情報も面白いと感じました。 – jimifiki
関数は '__get__'を実装します。これは、"
というテキストを返すものです。gettersとsetterを使用して、クラス自体ではなくクラスの個々のプロパティに適用する方がはるかに一般的です。また、基本的なオブジェクトクラスから継承しない関数もあります。カスタムビヘイビアが必要な場合は、クラスで実装することができます。技術的には独自の関数クラスを作成することはできますが、それは非常に遅く複雑になります。ベースオブジェクトクラスから継承しないことで、Pythonはコードオブジェクトの呼び出しを管理する代わりにCコードを実行できます – Aaron
"プレーン関数"とはなんですか? –
あなたの意見に関数オブジェクトと関数が何であるかの例を挙げてください。 –
これは、Pythonでの*単純な 'int' *と' int'オブジェクト*の違いは何ですか?これは単純な 'int's *ではありません。 –