迭代对象的“公共”属性

时间:2012-01-20 00:48:00

标签: python

最近,我发现自己编写了这样的代码:

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

是否有更多pythonic方式来访问对象的“公共”命名空间?

3 个答案:

答案 0 :(得分:16)

您可以使用vars function代替。

例如:

>>> 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'}

请注意,正如Niklas R指出的那样,具有单个下划线的变量也被视为私有。但是vars()函数的优点是可以消除除实例变量之外的所有变量。

答案 1 :(得分:15)

您可以在:

之前准备“公共”属性列表(列表或生成器)
>>> public_props = (name for name in dir(object) if not name.startswith('_'))
>>> for name in public_props:
    print name

但请在文档中阅读有关dir()功能的说明:

  

注意由于提供dir()主要是为了方便在交互式提示下使用,因此它会尝试提供一组有趣的名称,而不是尝试提供严格或一致的定义一组名称,其详细行为可能会在不同版本中发生变化。例如,当参数是类时,元类属性不在结果列表中。

您还应该知道,任何类都可以实现__dir__()方法,该方法可能返回不一定与属性名称对应的名称列表。换句话说,dir(something)并不保证结果会返回something的属性。

答案 2 :(得分:1)

我觉得迭代列表理解比使用continue关键字更加pythonic,但它可能只是一个品味问题。诚然,它比你已经拥有的要优雅得多。

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

注意:单下划线属性也不是“公开”。