Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/295.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 迭代对象';s";“公众”;属性_Python - Fatal编程技术网

Python 迭代对象';s";“公众”;属性

Python 迭代对象';s";“公众”;属性,python,Python,最近,我发现自己在写这样的代码: for name in dir( object ): if name.startswith( '__' ) : continue ... 对于目录中的名称(对象): 如果name.startswith(''.''):继续 ... 是否有更具python风格的方法来访问对象的“公共”命名空间?您可以使用 例如: >>> class C(object): ... def __init__(self): ... self.

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

for name in dir( object ): if name.startswith( '__' ) : continue ... 对于目录中的名称(对象): 如果name.startswith(''.''):继续 ... 是否有更具python风格的方法来访问对象的“公共”命名空间?

您可以使用

例如:

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