Pythonイントロスペクション:オブジェクト属性の「未分類」リストを取得する方法は?

StackOverflow https://stackoverflow.com/questions/640479

質問

次のコード

import types
class A:
    class D:
        pass
    class C:
        pass
for d in dir(A):
    if type(eval('A.'+d)) is types.ClassType:
        print d

出力

C
D

これらのクラスがコードで定義された順序で出力するにはどうすればよいですか?つまり、

D
C

inspect.getsource(A)を使用して解析する以外の方法はありますか?

役に立ちましたか?

解決

inspect モジュールには、 findsource 関数もあります。オブジェクトが定義されているソース行と行番号のタプルを返します。

>>> import inspect
>>> import StringIO
>>> inspect.findsource(StringIO.StringIO)[1]
41
>>>

findsource 関数は、実際にソースファイルを検索し、クラスオブジェクトが与えられている場合に候補を探します。

メソッド、関数、トレースバック、フレーム、またはコードオブジェクトを指定すると、(含まれている)コードオブジェクトの co_firstlineno 属性を単純に参照します。

他のヒント

検査ではすでに解析が行われていることに注意してください- inspect.findsource を見てください。これはモジュールでクラス定義を検索し、ソースと行番号を返します。その行番号でソートすると(個別のモジュールで定義されたクラスを分割する必要がある場合もあります)、正しい順序が与えられます。

ただし、この関数は文書化されていないようで、正規表現を使用して行を検索しているだけなので、あまり信頼性が高くない場合があります。

別のオプションは、メタクラスを使用するか、オブジェクトへの情報を暗黙的または明示的に順序付ける他の方法です。例:

import itertools, operator

next_id = itertools.count().next

class OrderedMeta(type):
    def __init__(cls, name, bases, dct):
        super(OrderedMeta, cls).__init__(name, bases, dct)
        cls._order = next_id()

# Set the default metaclass
__metaclass__ = OrderedMeta

class A:
    class D:
        pass
    class C:
        pass

print sorted([cls for cls in [getattr(A, name) for name in dir(A)] 
           if isinstance(cls, OrderedMeta)], key=operator.attrgetter("_order"))

ただし、これはかなり面倒な変更です(OrderedMetaに関心のあるクラスのメタクラスを設定する必要があります)

いいえ、探している順序でこれらの属性を取得することはできません。 Python属性は、挿入順序を認識しない辞書(ハッシュマップ)に保存されます。

また、単に言うことでevalの使用を避けます

if type(getattr(A, d)) is types.ClassType:
    print d
ループ内で

A .__ dict __

でキー/値のペアを繰り返し処理することもできます。

わかりません、ありません-ありません*。これは、クラスのすべての属性がディクショナリに格納されているためです(ご存じのとおり、順序付けされていません)。

*:実際には可能かもしれませんが、デコレータまたはメタクラスのハッキングが必要になります。どちらか興味がありますか?

ここではglibになろうとはしていませんが、ソースのクラスをアルファベット順に整理することは可能でしょうか? 1つのファイルに多くのクラスがある場合、これはそれ自体で役立つことがあります。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top