Python equivalent of Java's getClass().getFields()
我将一段代码从Java转换为Python,我不知道如何翻译以下内容:
1 2 3 |
在python中,可以查询对象与
1 2 3 4 5 | >>> class A: ... def foo(self): return"bar" ... >>> A.__dict__ {'__module__': '__main__', 'foo': <function foo at 0x7ff3d79c>, '__doc__': None} |
另外,这也是从C的角度提出的:如何在Python中枚举对象的属性?
您可以使用inspect.getmembers(object[,predicate]),而不是直接使用
首先,我要强调的是,在python中没有像
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | >>> class Foo(object): ... def __init__(self, value): ... # The __init__ method will create a field ... self.value = value ... >>> foo = Foo(42) >>> foo.value 42 >>> # Accessing inexistent field ... foo.another_value Traceback (most recent call last): File"<stdin>", line 2, in <module> AttributeError: 'Foo' object has no attribute 'another_value' >>> # Creating the field ... foo.another_value = 34 >>> # Now I can use it ... foo.another_value 34 |
所以,您不能从类中获取字段。相反,您可以从对象中获取字段。
另外,python方法只是具有一些特殊值的字段。方法只是函数的实例:
1 | >>> type(foo.__init__) |
需要注意的是,为了清楚地表明,在python中没有像
也就是说,如何获得字段(或属性,正如在Python中经常调用的那样)?当然,您不能从类中获取它们,因为对象存储它们。因此,可以使用
1 2 3 4 5 | >>> dir(foo) ['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'another_value', 'value'] |
一旦获得了属性名,就可以使用
1 2 | >>> getattr(foo, 'value') 42 |
要获得所有这些信息,可以使用列表理解:
1 2 3 4 5 6 | >>> [getattr(foo, attrname) for attrname in dir(foo)] [<class '__main__.Foo'>, <method-wrapper '__delattr__' of Foo object at 0x2e36b0>, {'another_value': 34, 'value': 42}, None, <built-in method __format__ of Foo object at 0x2e36b0>, <method-wrapper '__getattribute__' of Foo object at 0x2e36b0>, ... # Lots of stuff 34, 42] |
最后,您可以找到在某些属性上设置的值。
但是,此列表也将包含方法。记住它们也是属性。在这种情况下,我们可以使列表理解避免可调用的属性:
1 2 | >>> [attrname for attrname in dir(foo) if not callable(getattr(foo, attrname))] ['__dict__', '__doc__', '__module__', '__weakref__', 'another_value', 'value'] |
现在,获取实际值:
1 2 3 | >>> [getattr(foo, attrname) for attrname in dir(foo) ... if not callable(getattr(foo, attrname))] [{'another_value': 34, 'value': 42}, None, '__main__', None, 34, 42] |
还有一些奇怪的值,比如
1 2 3 4 5 6 7 8 | >>> [attrname for attrname in dir(foo) ... if not attrname.startswith('__') and ... not callable(getattr(foo, attrname))] ['another_value', 'value'] >>> [getattr(foo, attrname) for attrname in dir(foo) ... if not attrname.startswith('__') and ... not callable(getattr(foo, attrname))] [34, 42] |
还有其他方法可以做到这一点。例如,可以查看对象的
再编辑两个点。首先,cls解决方案非常好,因为它建议您查看
另外,您可能需要同时获取属性的名称和值。您可以让它生成一个元组列表:
1 2 3 4 | >>> [(attrname, getattr(foo, attrname)) for attrname in dir(foo) ... if not attrname.startswith('__') and ... not callable(getattr(foo, attrname))] [('another_value', 34), ('value', 42)] |
幸运的是,cls建议的inspect.getmembers()函数做得更好。
1 2 3 4 5 | >>> import inspect >>> inspect.getmembers(foo) [('__class__', <class '__main__.Foo'>), # ... Lots of stuff ... ('another_value', 34), ('value', 42)] |
要删除方法,只需避免调用:
1 2 | >>> inspect.getmembers(foo, lambda attr: not callable(attr)) [('__dict__', {'another_value': 34, 'value': 42}), ('__doc__', None), ('__module__', '__main__'), ('__weakref__', None), ('another_value', 34), ('value', 42)] |
(不幸的是,
还有很多内部的东西,我们不能像处理方法那样直接出来。列表理解无法再次解决的问题:
1 2 3 | >>> [(name, value) for name, value in inspect.getmembers(foo, lambda attr: not callable(attr)) ... if not name.startswith('__')] [('another_value', 34), ('value', 42)] |
Python是一种非常动态的语言,在某些情况下,这个解决方案不能很好地工作。考虑到有可能有一个对象,该对象应该存储一个要在某个地方使用的函数。函数是一个可调用的对象,不会显示属性。但是,它在逻辑上是一个属性,一个要使用的数据。你应该记住这种东西。不过,我敢打赌你不会经常遇到这样的问题。
高温高压
这不是一个确切的等价物,但是