Python 迭代对象';s";“公众”;属性
最近,我发现自己在写这样的代码: for name in dir( object ): if name.startswith( '__' ) : continue ... 对于目录中的名称(对象): 如果name.startswith(''.''):继续 ... 是否有更具python风格的方法来访问对象的“公共”命名空间?您可以使用 例如:Python 迭代对象';s";“公众”;属性,python,Python,最近,我发现自己在写这样的代码: for name in dir( object ): if name.startswith( '__' ) : continue ... 对于目录中的名称(对象): 如果name.startswith(''.''):继续 ... 是否有更具python风格的方法来访问对象的“公共”命名空间?您可以使用 例如: >>> class C(object): ... def __init__(self): ... self.
>>> 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()
函数的优点是,除了实例变量之外,它还可以消除所有变量。我觉得迭代列表理解比使用continue
关键字稍微有点像python,但这可能只是一个品味问题。无可否认,它并不比你已经拥有的东西优雅多少
for attr in (a for a in dir(object) if not a.startswith('_')):
pass
注意:单下划线属性也不是“公共”属性。您可以在以下操作之前准备“公共”属性列表(作为列表或作为生成器):
但请阅读文档中关于dir()
函数的注释:
注意因为提供dir()
主要是为了方便在交互提示下使用,所以它尝试提供一组有趣的名称,而不是严格或一致定义的名称,其详细行为可能会在不同版本中发生变化。例如,当参数是类时,元类属性不在结果列表中
您还应该知道,任何类都可以实现
\uuuu dir\uuuu()
方法,该方法可能返回不一定与属性名称对应的名称列表。换句话说,dir(something)
不能保证结果将返回something的属性
您首先要解决的问题是,这个构造有用吗?对于过滤器中的名称(lambda x:not x.startswith(“'),dir(obj)):?请注意,在Python中,即使只有一个下划线(
)也表示“private”属性。@NiklasR表示name in(x表示dir(obj)中的x),如果不是x.startswith(“”):
不需要过滤器It’奇怪的是,这个问题被标记为6个月后提出的问题的副本……奇怪的是,这是在问题提出5年后发生的!我得到TypeError:vars()参数必须具有uuu dict\uuuu属性
当在其他一些对象上尝试此操作时,vars()
函数只能在具有dict\uuuuu属性的对象上使用。因此,例如,如果在类上定义了\uuuuuu slots\uuuuu
,那么您将无法使用vars()
函数。还要注意,这不会得到任何属性,因此不仅仅是\uuuuuuu slots\uuuuu
无法工作。是否有理由选择dir(对象)
到对象。\uuuuu dict\uuuuu
对象。\uuuu dict\uuuuuu不一定返回您想要的属性,至少在我的测试结果中是这样。
>>> public_props = (name for name in dir(object) if not name.startswith('_'))
>>> for name in public_props:
print name