に呼び出されたとき?Pythonのクラスメソッドの実行別の方法は、次のように私はクラスを持っている
答えて
いいえ、これを行うにはクラスにフックがありません。メソッドは属性でもですが、インスタンス上の関数オブジェクトにアクセスするときに生成されるという点では多少異なります。機能はdescriptorsです。メソッドオブジェクトへ
コールは、メソッドオブジェクトを生成するとは別のステップです:
>>> class Foo(object):
... def bar(self):
... return 'bar method on Foo'
...
>>> f = Foo()
>>> f.bar
<bound method Foo.bar of <__main__.Foo object at 0x100777bd0>>
>>> f.bar is f.bar
False
>>> stored = f.bar
>>> stored()
'bar method on Foo'
ディスクリプタプロトコルを起動するobject.__getattribute__()
methodの作業ですので、あなたがすることにフックができメソッドが生成されたときを参照してくださいが、を呼び出すを生成すると、を呼び出すメソッドオブジェクトがを呼び出す必要があります。たとえば、実際のメソッドの代理を行う__call__
methodのオブジェクトを返すことができます。
しかし、呼び出されるたびにカウンタをインクリメントするデコレータで各メソッドを飾る方が簡単です。あなたはまだあなたのクラス内のすべての機能にこれを適用する必要があると思い
from functools import wraps
def method_counter(func):
@wraps(func)
def wrapper(self, *args, **kwargs):
self.methodCalls += 1
return func(self, *args, **kwargs)
return wrapper
:あなたが一緒にself
に合格する必要がありますので、それは、バインドされているデコレータが前に機能に適用さを考慮してください。あなたがカウントしたいすべてのメソッドにこれを手動で適用することができます:
class MyClass(object):
def __init__(self):
self.foo = "foo"
self.bar = "bar"
self.methodCalls = 0 #tracks number of times any function method is run
@method_counter
def get_foo(self):
return self.foo
@method_counter
def get_bar(self):
return self.bar
をしたり、メタクラスを使用することができます。
import types
class MethodCounterMeta(type):
def __new__(mcls, name, bases, body):
# create new class object
for name, obj in body.items():
if name[:2] == name[-2:] == '__':
# skip special method names like __init__
continue
if isinstance(obj, types.FunctionType):
# decorate all functions
body[name] = method_counter(obj)
return super(MethodCounterMeta, mcls).__new__(mcls, name, bases, body)
def __call__(cls, *args, **kwargs):
# create a new instance for this class
# add in `methodCalls` attribute
instance = super(MethodCounterMeta, cls).__call__(*args, **kwargs)
instance.methodCalls = 0
return instance
これはあなたのためのmethodCalls
属性を設定し、すべてのデコレータのニーズの世話をします、後者のアプローチの
class MyClass(object):
__metaclass__ = MethodCounterMeta
def __init__(self):
self.foo = "foo"
self.bar = "bar"
def get_foo(self):
return self.foo
def get_bar(self):
return self.bar
デモ:
ので、あなたのクラスはにはありません。>>> class MyClass(object):
... __metaclass__ = MethodCounterMeta
... def __init__(self):
... self.foo = "foo"
... self.bar = "bar"
... def get_foo(self):
... return self.foo
... def get_bar(self):
... return self.bar
...
>>> instance = MyClass()
>>> instance.get_foo()
'foo'
>>> instance.get_bar()
'bar'
>>> instance.methodCalls
2
は、上記メタクラスのみ関数(SO def
文とlambda
式の結果)装飾用のクラス本体の一部をオブジェクト考慮する。他の呼び出し可能なオブジェクト(functools.partial
オブジェクトのような__call__
メソッドを持つタイプがさらにあります)、の後に追加される関数はです。
優秀な答え渡された場合にのみ付きメソッド呼び出し、または直接にカウンターの増分を持つことができる - 私が後だった正確に何を。ありがとう! – techydesigner
ノーフックの声明に反対、そう – Mixone
@Mixoneを行うことは完全に可能である:クラスには*直接フックは*ありません。メソッドがどのように作成されるのか、それらのオブジェクトを呼び出す方法を理解する必要があります。 –
- 1. は、次のように私はクラスを持っているクラス
- 2. Pythonは次のように私はURLを持っている
- 3. 私は次のようにUiCollectionViewCellクラスを持っている
- 4. JAXB、私は次のようなクラスを持っている
- 5. はどのように繰り返し、私は次のように実行されるPythonスクリプトを持って
- 6. クラス、参照は次のように私はクラスを持っているメモリ
- 7. VBAは次のように私は、コードを持っているシェルコマンドを実行するが、別のディレクトリ
- 8. GORMは、私は次のようにクラスSheetLayoutを持ってADDTO
- 9. ブロックフローの実行は、私は、次のコードを持っている
- 10. 私は次のような実装を持っているカテゴリ
- 11. は、次のように私は、親と子のクラスを持っているPHP
- 12. は、次のように私はサブを持っている別のサブ
- 13. Pythonは、私は次のコードを持っている一行
- 14. は、次のように私はプログラムを持っているのpython
- 15. パンダ:次のように私はパンダのデータフレームを持っている別の列
- 16. スレッドは次のように私はクラス(単純化の例を)持っている特定の方法
- 17. 活字体は、次のように私はCSHARPクラスを持っているJSON
- 18. ジェネリックプッシュは、私は次のように定義Nodeクラスを持っているコンパイルエラー
- 19. 次のように私はクラスの構造とデータを持っている
- 20. 次のように私はprototxtを持ってどのようにPythonの
- 21. は、私は次のコードを持っている別のクラスのオブジェクト
- 22. は、私は次のようになりますファイル持っているのpython
- 23. は、私は次のPythonコードを持っているのPython
- 24. は、私はPythonで、次のコードを持っているのpython
- 25. R:次のように私は、データセットを持っている別の列
- 26. フィルタ行は次のように私は、クエリを持っているPostgreSQLの
- 27. 私は次のクラス持っ
- 28. 私は、次のクラス持っ
- 29. 私は次のクラス持っ
- 30. は、私は次のように私は、目標を持っているのbuild.xmlを持っているのAnt
メソッドも属性で、 '__getattr__'は属性が* missing *の場合にのみアクセスされます。 –
@MartijnPieters私は質問を洗練し、より良い例を見つけるでしょう。 – techydesigner
@MartijnPieters質問は洗練された。 – techydesigner