問題タブ [python-descriptors]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
python - CPython 組み込みを使用して、任意の呼び出し可能オブジェクトをバインドされていないクラス メソッドとして動作させる組み込みの方法はありますか?
Python 2 では、任意の callable をクラスのメソッドに変換することができました。重要なのは、callable が C で実装された CPython 組み込みである場合、これを使用して、それ自体が C レイヤーであるユーザー定義クラスのメソッドを作成し、呼び出されたときにバイト コードを呼び出さないことです。
これは、「ロックのない」同期を提供するために GIL に依存している場合に役立つことがあります。GIL は op コード間でしか交換できないため、コードの特定の部分のすべてのステップを C にプッシュできる場合は、アトミックに動作させることができます。
Python 2 では、次のようなことができます。
Python 3 では、バインドされていないメソッド型はなくなり、types.MethodType
2 つの引数のみを取り、バインドされたメソッドのみを作成します (これは__len__
、__hash__
、 などの Python の特殊なメソッドには役に立ちません。特殊なメソッドは、多くの場合、型で直接検索されるため、インスタンスではありません)。
私が見逃しているPy3でこれを達成する方法はありますか?
私が見たもの:
functools.partialmethod
(C実装がないように見えるため、要件に失敗し、Python実装と必要以上に汎用的であるため、遅く、テストで約5 usかかりますが、直接の場合は約200〜300 nsかかりますPython 定義またはattrgetter
Py2 では、オーバーヘッドが約 20 倍増加します)attrgetter
非データ記述子プロトコルに従おうとするなど(AFAICTでは不可能、a__get__
などでモンキーパッチを適用できない)attrgetter
を与えるためにサブクラス化する方法を見つけようとしています__get__
が、もちろん、__get__
何らかの方法で C レイヤーに委譲する必要があり、今では最初の場所に戻っています。attrgetter
(ユースケースに固有)__slots__
最初にメンバーを記述子にするために使用し、その後、データの結果の記述子から、実際の値をバインドして取得する最終ステップをスキップして、呼び出し可能にする何かに変換しようとしますしたがって、実際の値の取得は延期されます
ただし、これらのオプションのいずれについても、何かを見逃していないとは言えません。誰にも解決策はありますか?完全なハッキングが許可されています。私はここで病的なことをしていることを認識しています。柔軟であることが理想的です ( 、 、 などclass
の Python 組み込み関数、または Python レイヤーで定義されていないその他の呼び出し可能なオブジェクトから、バインドされていないメソッドのように動作するものを作成できるようにするため)。重要なことに、各インスタンスではなく、クラスにアタッチする必要があります (インスタンスごとのオーバーヘッドを削減し、ほとんどの場合インスタンス ルックアップをバイパスする特別なメソッドを正しく動作させるため)。hex
len
python - @classmethod が保持されているのに、@staticmethod がクラス間で保持されないのはなぜですか?
次のスクリプト例を見てください。
このスクリプトを Python 2.7.11 で実行すると、次のようになります。
@classmethod デコレータはクラス全体で保持されているようですが、 @staticmethod は保持されていません。
Python 3.4 は期待どおりに動作します。
Python2 が @staticmethod を保持しないのはなぜですか? 回避策はありますか?
編集:クラスから2つを取り出す(そして@staticmethodを保持する)ことはうまくいくようですが、それでも私には奇妙に思えます。