如何列出类的所有字段(没有方法)?

Eri*_*son 44 python introspection python-2.7

假设o是一个Python对象,我想要所有的字段o,没有任何方法或__stuff__.如何才能做到这一点?

我尝试过这样的事情:

[f for f in dir(o) if not callable(f)]

[f for f in dir(o) if not inspect.ismethod(f)]
Run Code Online (Sandbox Code Playgroud)

但这些返回相同dir(o),大概是因为dir给出了一个字符串列表.此外,__class__即使我让这个工作,这里也会返回.

Max*_*ant 55

您可以通过__dict__属性或内置vars函数获取它,这只是一个快捷方式:

>>> class A(object):
...     foobar = 42
...     def __init__(self):
...         self.foo = 'baz'
...         self.bar = 3
...     def method(self, arg):
...         return True
...
>>> a = A()
>>> a.__dict__
{'foo': 'baz', 'bar': 3}
>>> vars(a)
{'foo': 'baz', 'bar': 3}
Run Code Online (Sandbox Code Playgroud)

只有对象的属性.方法和类属性不存在.

  • 这是每个实例。 (4认同)
  • 这可能是您将获得的最佳近似值,但应该注意的是,这会将可调用实例属性(有时使用并且实际上类似于方法)视为非方法,并将类属性视为没有对应的实例属性而不是字段(即使它在大多数情况下都像一个字段).它也忽略了属性并且在带有`__slots__`的类上失败,这可能或不重要. (4认同)
  • 如果未定义 __dict __ 也不起作用。但情况并非总是如此。 (4认同)

Bre*_*arn 8

基本答案是"你不能可靠地这样做".看到这个问题.

你可以得到一个近似值[attr for attr in dir(obj) if attr[:2] + attr[-2:] != '____' and not callable(getattr(obj,attr))].

但是,你不应该依赖于此,因为:

因为dir()它主要是为了方便在交互式提示中使用而提供的,所以它试图提供一组有趣的名称,而不是尝试提供严格或一致定义的名称集,并且其详细行为可能会在不同版本中发生变化.

换句话说,没有规范的方法来获取"所有对象的属性"(或"所有对象的方法")的列表.

如果您正在进行某种动态编程,需要您迭代对象的unknwon字段,唯一可行的方法是实现自己的方法来跟踪这些字段.例如,您可以使用属性命名约定或特殊的"字段"对象,或者最简单的使用字典.

  • @ 2rs2ts:是的,这是真的.没有办法解决这个问题.没有办法以编程方式判断双下划线名称是否"神奇"; 你必须阅读文档. (3认同)
  • 这些是命名约定,您不应该通过用双下划线围绕它们来创建自己的成员. (3认同)

Ben*_*ueg 7

这应该适用于可调用对象:

[f for f in dir(o) if not callable(getattr(o,f))]
Run Code Online (Sandbox Code Playgroud)

您可以通过以下方式摆脱其余部分:

[f for f in dir(o) if not callable(getattr(o,f)) and not f.startswith('__')]
Run Code Online (Sandbox Code Playgroud)


bvi*_*dal 7

您可以使用内置方法 vars()


mar*_*eau 6

您可以遍历实例的__dict__属性并查找非方法的东西。例如:

CALLABLES = types.FunctionType, types.MethodType
for key, value in A().__dict__.items():
    if not isinstance(value, CALLABLES):
        print(key)
Run Code Online (Sandbox Code Playgroud)

输出:

CALLABLES = types.FunctionType, types.MethodType
for key, value in A().__dict__.items():
    if not isinstance(value, CALLABLES):
        print(key)
Run Code Online (Sandbox Code Playgroud)

您可以在单个语句中使用列表理解来做到这一点:

print([key for key, value in A.__dict__.items() if not isinstance(value, CALLABLES)])
Run Code Online (Sandbox Code Playgroud)

哪个会打印['foo', 'bar']