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