14

クラス内のすべてのメソッドの名前を取得しようとしています。inspect モジュールがどのように機能するかをテストするときに、メソッドの 1 つをobj = MyClass.__dict__['mymethodname'].

しかし、今はwhile inspect.ismethod(obj)returnsを返しますが、その理由がわかりません。メソッドを認識していないメソッドとしてマークする奇妙な方法はありますか? クラスで定義されており、最初の引数として取るだけだと思いました。Falseinspect.isfunction(obj)Trueself

4

5 に答える 5

11

Pythonの舞台裏の機械のいくつかの効果が見られます。

を書くf = MyClass.__dict__['mymethodname']と、プレーンな関数である「mymethodname」の生の実装が得られます。これを呼び出すには、追加のパラメーターであるクラスインスタンスを渡す必要があります。

書くとf = MyClass.mymethodname(mymethodnameの後に括弧がないことに注意してください)、クラスMyClassのバインドされていないメソッドを取得します。これは、MethodType上記で取得した生の関数をラップするインスタンスです。これを呼び出すには、追加のパラメーターであるクラスインスタンスを渡す必要があります。

あなたが書くときf = MyClass().mymethodname(私がそのメソッドを取る前にクラスMyClassのオブジェクトを作成したことに注意してください)、あなたはクラスMyClassのインスタンスのバインドされたメソッドを取得します。すでに内部に格納されているため、追加のクラスインスタンスを渡す必要はありません。

文字列として指定された名前でラップされたメソッド(バインドまたは非バインド)を取得するには、 gnibblergetattrで示されているように、を使用します。例えば:

unbound_mth = getattr(MyClass, "mymethodname")

また

bound_mth = getattr(an_instance_of_MyClass, "mymethodname")
于 2010-07-12T13:23:34.180 に答える
3

ソースを使用する

def ismethod(object):
    """Return true if the object is an instance method.
    Instance method objects provide these attributes:
        __doc__         documentation string
        __name__        name with which this method was defined
        __func__        function object containing implementation of method
        __self__        instance to which this method is bound"""
    return isinstance(object, types.MethodType)

最初の議論selfは慣例によるものです。クラスのdictから名前でメソッドにアクセスすることにより、バインディングをバイパスしているため、メソッドではなく関数のように見えます

名前でメソッドにアクセスする場合は、

getattr(MyClass, 'mymethodname') 
于 2010-07-12T13:06:27.130 に答える
1

さて、それobj.mymethodはメソッド (暗黙的に渡されたself) でKlass.__dict__['mymethod']あり、関数であるということですか?

基本的には、記述子Klass.__dict__['mymethod']と呼ばれるものによってメソッドに変換できる「生の」関数です。つまり、クラスのすべての関数は、アクセス方法に応じて、通常の関数とメソッドの両方になることができます。これは、クラス システムが Python でどのように機能するかであり、非常に正常です。

メソッドが必要な場合は、行くことはできません__dict__(とにかくすべきではありません)。あなたがすべきすべてのメソッドを取得するにはinspect.getmembers(Klass_or_Instance, inspect.ismethod)

詳細はこちらで読むことができます。これに関する説明は「ユーザー定義メソッド」にあります。

于 2010-07-12T13:10:11.010 に答える
1

@ THC4kの回答に対するコメントから、OPは組み込みメソッドと純粋なPythonコードで定義されたメソッドを区別したいようです。ユーザー定義メソッドはありますがtypes.MethodType、組み込みメソッドはそうではありません。

次のようにさまざまなタイプを取得できます。

import inspect
import types

is_user_defined_method = inspect.ismethod

def is_builtin_method(arg):
    return isinstance(arg, (type(str.find), type('foo'.find)))

def is_user_or_builtin_method(arg):
    MethodType = types.MethodType
    return isinstance(arg, (type(str.find), type('foo'.find), MethodType))

class MyDict(dict):
    def puddle(self): pass

for obj in (MyDict, MyDict()):
    for test_func in (is_user_defined_method, is_builtin_method,
            is_user_or_builtin_method):
        print [attr 
            for attr in dir(obj)
            if test_func(getattr(obj, attr)) and attr.startswith('p')]

これは次を印刷します:

['puddle']
['pop', 'popitem']
['pop', 'popitem', 'puddle']
['puddle']
['pop', 'popitem']
['pop', 'popitem', 'puddle']
于 2010-07-12T16:37:25.567 に答える
0

dirを使用して、使用可能なメソッド/属性/などの名前を取得し、それらを繰り返し処理して、どれがメソッドであるかを確認できます。このような:

[ mthd for mthd in dir(FooClass) if inspect.ismethod(myFooInstance.__getattribute__(mthd)) ]

よりクリーンなソリューションがあることを期待していますが、これは、他に誰も思い付かない場合に使用できるものになる可能性があります。getattribute を使用するためにクラスのインスタンスを使用する必要がなかったらいいのにと思います。

于 2010-07-12T13:07:50.183 に答える