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

Python 如何列出类的所有字段(没有方法)?,python,python-2.7,introspection,Python,Python 2.7,Introspection,假设o是一个Python对象,我想要o的所有字段,不带任何方法或\uuuuuuuuuuuuuuuuuuuuuuu。如何做到这一点 我试过这样的方法: [f for f in dir(o) if not callable(f)] [f for f in dir(o) if not inspect.ismethod(f)] 但是它们返回的值与dir(o)相同,可能是因为dir给出了一个字符串列表。此外,类似于\uuuuu class\uuuuuu的内容将在此处返回,即使我让它工作。这应该适用于可

假设
o
是一个Python对象,我想要
o
的所有字段,不带任何方法或
\uuuuuuuuuuuuuuuuuuuuuuu
。如何做到这一点

我试过这样的方法:

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

[f for f in dir(o) if not inspect.ismethod(f)]

但是它们返回的值与
dir(o)
相同,可能是因为
dir
给出了一个字符串列表。此外,类似于
\uuuuu class\uuuuuu
的内容将在此处返回,即使我让它工作。

这应该适用于可调用项:

[f for f in dir(o) if not callable(getattr(o,f))]
您可以通过以下方式摆脱其余部分:

[f for f in dir(o) if not callable(getattr(o,f)) and not f.startswith('__')]

您可以通过
\uuuu dict\uuuu
属性或函数获取它,这只是一个快捷方式:

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

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

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

基本答案是“您不能可靠地这样做”。看

如果attr[:2]+attr[-2:]!=“\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu”且不可调用(getattr(obj,attr))],则可以使用
[attr for attr in dir(obj))获得近似值

然而,你不应该依赖于这个:

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

换句话说,没有标准的方法可以获得“对象的所有属性”(或“对象的所有方法”)的列表


如果您正在执行某种动态编程,需要迭代对象的未知字段,那么唯一可靠的方法就是实现您自己跟踪这些字段的方法。例如,您可以使用一个属性命名约定,或者一个特殊的“字段”对象,或者最简单的是一个字典。

您可以迭代实例的
\u dict\u
属性并查找非方法的内容。 例如:

CALLABLES = types.FunctionType, types.MethodType
for key, value in A().__dict__.items():
    if not isinstance(value, CALLABLES):
        print(key)
输出:

foo
酒吧
您可以在一条语句中使用以下命令执行此操作:


这将打印
['foo',bar']

这是每个实例。这可能是您将获得的最佳近似值,但应注意,这考虑了可调用实例属性(有时使用,并且与方法非常类似)作为非方法,并认为没有相应实例属性的类属性不是字段(即使在大多数情况下它的行为类似于字段)。它也会忽略属性,并在带有
\uuuuuuu插槽的类上失败,这可能很重要,也可能无关紧要。我得到了
[''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''./code>,带有一个伪类成员为
a
的伪类。关闭,但仍然包括
'.''''>'.'.''''.'''''.''''''.'''''''.'代码>>模块'.',这是真的。这是没有办法的。无法通过编程判断双下划线名称是否“神奇”;你必须阅读文档。这些是命名约定,你不应该用双下划线来创建你自己的成员。@Benjamin:的确如此。在本节的末尾,关于带有双下划线前缀和后缀的名称,它说“永远不要发明这样的名称;只在文档中使用它们。”我一直在尝试,但不能100%正确,但该模块可能会有所帮助?我还研究了inspect…可能的重复,没有必要过滤掉方法,因为它们在类
\uuuuu dict\uuuu
中,而不是实例
\uuuuuu dict\uuuu
s中。@Blckknght:我之所以进行测试,是因为类也是一个对象。然而,在你的评论之后,我意识到需要检查不止一种类型的callable,并修改了我的答案。谢谢如果可以假设对象是一个新型的类实例,那么您所说的是正确的,并且可以简化
循环的
。我赞成调用其他方法,而不是Python中混乱的神奇方法和属性。我认为这是一种更具python风格的方式。以我的+1为例。
print([key for key, value in A.__dict__.items() if not isinstance(value, CALLABLES)])