クラス内の関数の宣言の順序を発見できると非常に役立つプロジェクトに取り組んでいます。基本的に、クラス内のすべての関数が宣言された順序で実行されることを保証できるようにしたいと考えています。
最終結果は、関数の出力の順序が関数が宣言された順序と一致する Web ページです。このクラスは、それを Web ページとして定義する一般的な基本クラスから継承されます。Web アプリケーションは .py ファイルを動的に読み込みます。
クラス内の関数の宣言の順序を発見できると非常に役立つプロジェクトに取り組んでいます。基本的に、クラス内のすべての関数が宣言された順序で実行されることを保証できるようにしたいと考えています。
最終結果は、関数の出力の順序が関数が宣言された順序と一致する Web ページです。このクラスは、それを Web ページとして定義する一般的な基本クラスから継承されます。Web アプリケーションは .py ファイルを動的に読み込みます。
from types import MethodType, FunctionType
methodtypes = set((MethodType, FunctionType, classmethod, staticmethod))
def methods_in_order(cls):
"Given a class or instance, return its methods in the order they were defined."
methodnames = (n for n in dir(cls) if type(getattr(cls, n)) in methodtypes)
return sorted((getattr(cls, n) for n in methodnames),
key=lambda f: getattr(f, "__func__", f).func_code.co_firstlineno)
使用法:
class Foo(object):
def a(): pass
def b(): pass
def c(): pass
print methods_in_order(Foo)
[<unbound method Foo.a>, <unbound method Foo.b>, <unbound method Foo.c>]
インスタンスでも動作します:
print methods_in_order(Foo())
継承されたメソッドが別のソース ファイルで定義されている場合、順序が一貫していない可能性があります (並べ替えは、独自のソース ファイル内の各メソッドの行番号に依存するため)。これは、クラスのメソッド解決順序を手動でウォークすることで修正できます。これはかなり複雑になるので、ここでは説明しません。
または、クラスで直接定義されたもののみが必要な場合は、説明したアプリケーションに役立つように思われます。次を試してください。
from types import MethodType, FunctionType
methodtypes = set((MethodType, FunctionType, classmethod, staticmethod))
def methods_in_order(cls):
"Given a class or instance, return its methods in the order they were defined."
methodnames = (n for n in (cls.__dict__ if type(cls) is type else type(cls).__dict__)
if type(getattr(cls, n)) in methodtypes)
return sorted((getattr(cls, n) for n in methodnames),
key=lambda f: getattr(f, "__func__", f).func_code.co_firstlineno)
これは新しいスタイルのクラスを想定しています。