1 つの解決策は、メソッドdir
を追加する前にのコピーを作成することです。__getattr__
class Hal(object):
def __init__(self):
self._names = dir(self)
def __getattr__(self, name):
print self.names
self.__getattr__ = __getattr__
ただし、単純なケースでは、問題を解決するためにクラス オブジェクトでdir
(および同様getattr
に 、または などを)呼び出すことができます。inspect.getmembers
構築後にインスタンスにメソッドを追加できる場合、これは機能しませんが、それが問題にならない場合は簡単です。
names = dir(self.__class__)
ただし、名前を取得した後、メソッドをフィルター処理するには、いくつかの作業が必要です。
isinstance
まず、 onを使用してgetattr(self, name)
、それがメソッド ラッパーであることを確認します (または、バインドされたバージョンの型を取得し、それがインスタンス メソッドであることを確認します)。から値を直接取得した場合、好きな方法で名前を取得して または のいずれかself.__class__.__dict__
を呼び出した場合とまったく同じものは得られません。特に、インスタンス メソッドは として表示されます。これは、メソッド ラッパーよりも簡単にテストできます。他のケースのいくつかは現在、検出が難しくなっていますが。getattr(self, name)
getattr(self.__class__, name)
function
いずれにせよ、タイプに基づくものは、メソッドのように振る舞うがそうでないものを見つけることはありません (たとえば、組み込み関数をオブジェクトに直接割り当てたり、特定の種類のデコレータで何かをラップしたり、カスタム記述子を記述したり、関数としてメソッドを持つクラス__callable__
など)。何か凝ったことをしている場合 (または誰かが後で凝ったものを追加するのではないかと心配している場合) は、メンバーを明示的にバインドできるかどうか (または に偽装バインドできるかどうか) をテストしNone
、結果がcallable
であるかどうかを確認する必要があります。適切に呼び出し可能であることを確認するために、さらにテストを行う可能性があります (そうしないと、だまされるため)@staticmethod
および類似のもの)。本当に、これが発生した場合 (そして、あなたは自分のデザインを熟考し、自分自身と少なくとも 1 人の他の人にそれが正気ではないことを確信させました...)、考えられるすべてのことを、あなたが持っているすべてのケースに対してテストする必要があります...</ p>
Hal
メソッドがまたは別の基底クラスではなくインスタンスで定義されているかどうかを知りたい場合は、object
これを行う方法がいくつかありますが、最も簡単な方法は、基底クラスのメンバーを差し引くことです。(もちろん、インスタンスで定義されたメソッドを気にしない場合は、Hal.__dict__
すでに必要なものがあります。)