4

次のコード

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) を使用して解析する以外に方法はありますか?

4

6 に答える 6

8

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

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

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

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 に設定する必要があります)。

于 2009-03-12T21:51:30.053 に答える
5

いいえ、探している順序でこれらの属性を取得することはできません。Python属性は、挿入順序を認識しないdict(読み取り:ハッシュマップ)に格納されます。

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

if type(getattr(A, d)) is types.ClassType:
    print d

あなたのループで。でキーと値のペアを繰り返すこともできることに注意してくださいA.__dict__

于 2009-03-12T21:14:07.960 に答える
4

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

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

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

method-、function-、traceback-、frame-、またはcode-objectが与えられるとco_firstlineno、(含まれている)code-objectの属性を調べるだけです。

于 2009-03-12T22:03:07.903 に答える
1

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

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

于 2009-03-12T21:13:00.193 に答える
1
class ExampleObject:
    def example2():
        pass
    
    def example1():
        pass

context = ExampleObject

def sort_key(item):
    return inspect.findsource(item)[1]

properties = [
    getattr(context, attribute) for attribute in dir(context)
    if callable(getattr(context, attribute)) and 
    attribute.startswith('__') is False
]
properties.sort(key=sort_key)

print(properties)

印刷する必要があります:

[<関数 ExampleObject.example2 at 0x7fc2baf9e940>, <関数 ExampleObject.example1 at 0x7fc2bae5e790>]

私が構築しているいくつかのコンパイラにもこれを使用する必要があり、これは非常に役立つことがわかりました。

于 2021-12-18T03:41:05.317 に答える
0

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

于 2009-03-12T21:33:47.663 に答える