2009-03-30 12 views
4

変数が関数またはクラスメソッドのいずれかを参照している場合、クラスメソッドが特定の例のように宣言されている場合は、そのクラスがどれであるかを調べてクラスの型を取得するにはどうすればよいでしょうか。関数とクラスメソッドを区別する方法は?

例えば、

def get_info(function_or_method): 
    print function_or_method 

class Foo(object): 
    def __init__(self): 
     pass 

    get_info(__init__) 

def bar(): 
    pass 

get_info(bar) 

更新 はJFセバスチャンは、関数がクラス内で宣言されているとき、私はそれを区別できるようにするために触れたポイントを再び強調するためにダビデとJFセバスチャンからの最初の2つの応答の後に質問します(私が得るタイプが関数であり、バインドされたメソッドまたはバインドされていないメソッドではありません)。すなわち、 get_info(__init__)への最初の呼び出しが発生したところで、私はそのメソッドがクラスの一部として宣言されていることを検出できるようにしたいと考えています。

この質問は、私はその周りにデコレータを入れていますし、それがのinit機能へのハンドルを取得し、メソッドがクラス内またはスタンドアロン関数として宣言されている場合、私は実際に把握することはできませんので、思いつきました

+0

デコレータが結合していない機能や方法の機能の両方のために働くべきでない理由はありません。なぜあなたはこれをやろうとしていますか?なぜ2つのデコレータを持っていないのですか? –

答えて

3

JFセバスチャンはに触れたポイントを再び強調するために、私ができるようにしたいです関数がクラス内で宣言されているときに区別するために使用します(タイプが取得されるのは関数であり、バインドされたメソッドまたはバインドされていないメソッドではありません)。すなわち、 get_info(__init__)への最初の呼び出しが発生したところで、私はそのメソッドがクラスの一部として宣言されていることを検出できるようにしたいと考えています。

この質問は、私はその周りにデコレータを入れていますし、それがinit関数へのハンドルを取得し、メソッドがクラス内で、またはスタンドアローン機能

として宣言されている場合、私は実際に把握することはできませんので、思いつきました

できません。 J.F.セバスチャンの答えはまだ100%適用可能です。クラス定義の本体が実行されているとき、そのクラス自体はまだ存在しません。ステートメント(__init__関数定義、およびget_info(__init__)呼び出し)は新しいローカル名前空間で発生します。 get_infoへの呼び出しが発生した時点で、__init__はその名前空間内の関数への参照であり、クラス外で定義された関数と区別できません。

11

あなたはタイプをチェックすることにより、2つを区別することができます。

>>> type(bar) 
<type 'function'> 
>>> type(Foo.__init__) 
<type 'instancemethod'> 

または

>>> import types 
>>> isinstance(bar, types.FunctionType) 
True 
>>> isinstance(bar, types.UnboundMethodType) 
True 

をそれはあなたがifステートメントでそれを行う方法です。 __init__は通常の関数であるあなたは(クラス定義内)get_info(__init__)を呼び出しているときに

>>> Foo.__init__.im_class 
__main__.Foo 
+0

"<タイプ 'instancemethodは、'>" 'types.MethodType'クラス(でisinstance(フー.__ init__、types.MethodType)== TRUE)の(やや一貫性なく)文字列表現であることをそれは言及する価値があります。 – jfs

+0

はところで、でisinstance(バー、types.UnboundMethodType)は – jfs

+0

またFalseで、あなたは( 'でisinstanceを使用して' Fooの.__ init__'(非結合法)と 'Fooの().__ init__'(バインドされたメソッド)を区別することはできません... ) '。 'im_self'(' __self__' 2.6+)属性をチェックしてください。 – jfs

8

また、あなたは方法のim_class属性からクラスを取得することができます。

def get_info(function_or_method): 
    print function_or_method 

class Foo(object): 
    def __init__(self): 
     pass 
    get_info(__init__) # function 

def bar(): 
    pass 

get_info(Foo.__init__) # unbound method 
get_info(Foo().__init__) # bound method 
get_info(bar)   # function 

出力(CPythonと、IronPythonの):

<function __init__ at ...> 
<unbound method Foo.__init__> 
<bound method Foo.__init__ of <__main__.Foo object at ...>> 
<function bar at ...> 

出力(Jythonの):

<function __init__ 1> 
<unbound method Foo.__init__> 
<method Foo.__init__ of Foo instance 2> 
<function bar 3> 
関連する問題