迭代对象的"公共"属性

Wil*_*ell 12 python

最近,我发现自己编写的代码如下:

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

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

srg*_*erg 16

您可以改用该vars功能.

例如:

>>> 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'}
Run Code Online (Sandbox Code Playgroud)

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

  • 是的,`vars()`函数只能用于具有`__dict__`的对象.因此,例如,如果在您的类上定义了`__slots__`,那么您将无法使用`vars()`函数. (3认同)
  • 我得到`TypeError:vars()参数在其他一些对象上尝试时必须有__dict__属性 (2认同)
  • 还要注意,这不会得到任何属性,所以不只是`__slots__`的东西不起作用. (2认同)

Tad*_*eck 16

您可以在以下情况之前准备"公共"属性列表(作为列表或生成器):

>>> public_props = (name for name in dir(object) if not name.startswith('_'))
>>> for name in public_props:
    print name
Run Code Online (Sandbox Code Playgroud)

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

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

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