2012-01-20 14 views
11

属性、私は自分自身がこのようなコードを書く見つける:反復最近

 
for name in dir(object): 
    if name.startswith('__') : continue 
    ... 

は、オブジェクトの「公開」の名前空間にアクセスするためのより多くの神託の方法はありますか?

+2

どのような問題が最初に解決されていますか? – SingleNegationElimination

+0

フィルターの名前は何ですか(ラムダx:xstartswith( '_')、dir(obj)): '? Pythonでは、単一のアンダースコア( '_')でも*" private "*属性を示すことに注意してください。 –

+2

@NiklasR '(xはdir(obj)がx.startswith( '_')でない場合はxに入ります):'フィルタは不要です –

答えて

15

どのクラスも、属性の名前に必ずしも対応しない名前のリストを返す可能性がある__dir__()メソッドを実装できることにも注意してください。つまり、dir(something)は、結果がsomethingの属性を返すことを保証しません。

+1

'object .__ dict__'に' dir(object) 'を好む理由はありますか? – Dave

+1

オブジェクト.__ dict__は、少なくとも私のテスト結果から、必要な属性を必ずしも返すわけではありません。 –

15

代わりにvars functionを使用できます。例えば

:ニクラスRが指摘したように、単一の下線付き変数は、プライベートとみなされる、

>>> class C(object): 
... def __init__(self): 
...  self.__foo = 'foo' 
... 
>>> c = C() 
>>> dir(c) 
['_C__foo', '__class__', '__delattr__', '__dict__', '__doc__', '__format__', 
'__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__',  
'__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__',  
'__weakref__'] 
>>> vars(c) 
{'_C__foo': 'foo'} 

注意。しかし、vars()関数には、インスタンス変数以外のすべてを削除するという利点があります。

+2

他のオブジェクトでこれを試してみると 'TypeError:vars()引数に__dict__属性が必要です ' – wim

+2

はい、' vars() '関数は' __dict__'を持つオブジェクトに対してのみ使用できます。例えば、クラスに '__slots__'が定義されている場合、' vars() '関数を使うことはできません。 – srgerg

+1

これはプロパティであるものを取得しないので、動作しない '__slots__'を持つものだけではありません。 –

1

リストの反復は、continueというキーワードを使用するよりも少し難解ですが、それは味の問題かもしれません。それはあなたがすでに持っているものよりもはるかにエレガントではないことは間違いありません。

for attr in (a for a in dir(object) if not a.startswith('_')): 
    pass 

注:シングル下線属性も "公共" ではありません。あなたがすべき

Note Because dir() is supplied primarily as a convenience for use at an interactive prompt, it tries to supply an interesting set of names more than it tries to supply a rigorously or consistently defined set of names, and its detailed behavior may change across releases. For example, metaclass attributes are not in the result list when the argument is a class.

>>> public_props = (name for name in dir(object) if not name.startswith('_')) 
>>> for name in public_props: 
    print name 

しかし、ドキュメントのノートをお読みくださいについてdir()機能:あなたは前に(リストとしてまたは発電機のような)属性を「公共」のリストを準備することができます