3

私の質問はこれと似てます。モジュールの内容ではなく、オブジェクトのメソッドに関するものです。inspectモジュールを使用して、親ではなく、質問しているクラスでのみ定義されたメソッドを取得できるかどうかを知りたいです。

これが必要なのは、子クラスが「マクロ」メソッドを定義しているためです。これは、より高いレベルの抽象化で親のメソッドにアクセスし、ユーザーが継承のすべての方法で定義された低レベルのメソッドについて心配する必要がないようにしたいためです木。

簡単な例を次に示します。

class Foo(object):
    def __init__(self): pass
    def f1(self): return 3
    def f2(self): return 1

class Bar(Foo):
    def __init__(self): Foo.__init__(self)
    def g1(self): return self.f1() + self.f2()
    def g2(self): return self.f1() - self.f2()

import inspect
inspect.getmembers(Bar, inspect.ismethod)

出力:

[('__init__', <unbound method Bar.__init__>),
 ('f1', <unbound method Bar.f1>),
 ('f2', <unbound method Bar.f2>),
 ('g1', <unbound method Bar.g1>),
 ('g2', <unbound method Bar.g2>)]

fユーザーはs にしか興味がないので、 s の存在を知ったり気にしたりする必要はありませんg。(もちろん、これらのメソッドはすべて、オブジェクトがインスタンス化されるときにオブジェクトにバインドされるため、この出力はほとんどのコンテキストで意味があります。) 長い継承ツリーの場合、返されるリストは非常に長くなり、継承されていないものでいっぱいになる可能性があります。ユーザーには関係ありません。

このリストを離れf1たり外したりするにはどうすればよいですか? クラスで定義されたメソッドf2の属性に相当するものはありますか? さらに良いことに、インスタンスメソッド__module__で同じことを行うことは可能ですか?

4

2 に答える 2

5

メソッドには、im_class問題のクラスを指す属性があります。クラスのメンバーである関数でそのフィルターを使用できます。

inspect.getmembers(Bar,
    lambda m: inspect.ismethod(m) and m.__func__ in m.im_class.__dict__.values())

これにより、以下が得られます。

[
    ('__init__', <unbound method Bar.__init__>),
    ('f1', <unbound method Bar.f1>), 
    ('f2', <unbound method Bar.f2>)
]

もちろん、getmembers完全にバイパスすることもできます:

[m for m in Bar.__dict__.values() if inspect.isfunction(m)]

与えます:

[<function __init__ at 0x100a28de8>, <function g1 at 0x100a28e60>, <function g2 at 0x100a28ed8>]

これは、バインドされたメソッドまたはバインドされていないメソッドに適用され、同じ.__func__(またはim_func古い名前) 属性があります。バインドと非バインドの違いは、.__self__属性の値です (非バインドの場合は None)。

これらの「秘密の」属性はすべてPython Data Modelで文書化されています。

于 2012-08-13T12:31:43.817 に答える
2

うまくいけば、誰かがより良い解決策を見つけてくれるでしょうが、どうですか:

foo_members = inspect.getmembers(Foo,inspect.ismethod)
bar_members = inspect.getmembers(Bar,inspect.ismethod)

set(bar_members) - set(foo_members)

もちろん、実際の状況では、不要なBar.__bases__ものをすべて実際に取り除くために、手順を踏む必要がある場合があります。

例えば:

set(bar_members) - set(sum([inspect.getmembers(base,inspect.ismethod) for base in Bar.__bases__],[]))
于 2012-08-13T12:31:27.980 に答える