1

公式ドキュメントによると

オブジェクトに という名前のメソッドがある場合__dir__()、このメソッドが呼び出され、属性のリストを返す必要があります。__getattr__()これにより、カスタムまたは__getattribute__()関数を実装するオブジェクトはdir()、その属性を報告する方法をカスタマイズできます。

カスタム__dir__実装の場合、別の関数によって返される結果inspect.getmembers()も影響を受けます。

例えば:

class С(object):
    __slots__ = ['atr']
    def __dir__(self):
        return ['nothing']
    def method(self):
        pass
    def __init__(self):
        self.atr = 'string'

c = C() 
print dir(f) #If we try this - well get ['nothing'] returned by custom __dir__()
print inspect.getmembers(f) #Here we get []
print f.__dict__ #And here - exception will be raised because of __slots__

この場合、オブジェクトの名前のリストはどのように取得できますか?

4

2 に答える 2

4

元の質問への回答 -inspect.getmembers()使用は__dir__()好きdir()ですか?

inspect.getmembers()これが実際に何をしているのかを確認できるように、ソースコードを次に示します。

def getmembers(object, predicate=None):
    """Return all members of an object as (name, value) pairs sorted by name.                                                                                                                                     
    Optionally, only return members that satisfy a given predicate."""
    results = []
    for key in dir(object):
        try:
            value = getattr(object, key)
        except AttributeError:
            continue
        if not predicate or predicate(value):
            results.append((key, value))
    results.sort()
    return results

このことから、結果を少しフィルタリングしているだけであることがわかります。dir()

オーバーライドされた属性を取得する方法は__dir__()?

この回答によると、常に属性の完全なリストを取得することはできませんが、場合によってはそれらを確実に取得したり、有用な情報を十分に取得したりできます。

ドキュメントから:

オブジェクトが を提供しない場合、関数はオブジェクトの属性 (定義されている場合) およびその型オブジェクトから__dir__()情報を収集するために最善を尽くします。__dict__結果のリストは必ずしも完全ではなく、オブジェクトに custom がある場合は不正確になる可能性があります__getattr__()

したがって、 を使用していない場合は__slots__、オブジェクト (およびそれは型オブジェクト) を調べて、通常提供される__dict__情報と基本的に同じ情報を取得できます。dir()そのため、 と同様にdir()、より厳密な方法を使用してメタクラス メソッドを取得する必要があります。

を使用している場合__slots__、クラス属性の取得はある意味でもう少し簡単です。はい、辞書はありませんが__slots__、すべての属性の名前を含むそれ自体があります。たとえば、print c.__slots__サンプル コードに追加すると、 が生成されます['atr']。(ここでも、スーパークラスの属性を取得するには、より厳密なアプローチが必要です。)

メソッドの取得方法

ユース ケースによっては別のソリューションが必要になる場合がありますが、メソッドを簡単に見つけたい場合は、組み込みのhelp().

変更された PyPydir()

上記のいくつかの代替方法を次に示します。dir()ユーザー定義__dir__メソッドを無視するバージョンを取得するには、 PyPy の実装を取得して、メソッドdir()を参照する部分を削除するだけ__dir__です。

于 2012-12-16T05:15:13.960 に答える
0

マシューが他の回答で指摘したように、実際の属性である結果getmembersのサブセットを返すようです。dir

>>> class C:
>>>   def foo(self):
>>>     pass
>>>   def __dir__(self):
>>>     return ['test']
>>>
>>> import inspect
>>> c = C()
>>> dir(c)
['test']
>>> inspect.getmembers(c)
[]
于 2012-12-16T05:15:27.763 に答える