我正在将一段代码从Java转换为Python,我不知道如何翻译以下内容:
Field[] fields = getClass().getFields();
for (int i = 0; i < fields.length; i++ ) {
if (fields[i].getName().startsWith((String) param){ ....
答案 0 :(得分:9)
在Python中,您可以使用__dict__
查询对象的绑定,例如:
>>> class A:
... def foo(self): return "bar"
...
>>> A.__dict__
{'__module__': '__main__', 'foo': <function foo at 0x7ff3d79c>, '__doc__': None}
此外,这已经从C#的角度提出:How to enumerate an object's properties in Python?
您可以使用inspect.getmembers(object[, predicate]),而不是直接使用__dict__
,{{3}}有inspect.ismethod(object)
等有用的方法
答案 1 :(得分:7)
首先,我要强调Python中没有getClass().getFields()
这样的东西,因为一个对象可以有很多不是由类定义的字段。实际上,要在Python中创建一个字段,您只需要为其赋值。这些字段不是已定义,已创建:
>>> 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方法只是具有一些特殊值的字段。方法仅仅是函数的实例:
>>> type(foo.__init__)
重要的是要注意,要清楚说明Python中没有getClass().getMethods()
这样的方法,getClass().getFields()
的“等效”也将返回方法。
说,你怎么能得到字段(或属性,因为它们经常在Python中调用)?当然,你无法从类中获取它们,因为对象存储它们。因此,您可以使用dir()
函数获取对象属性的名称:
>>> dir(foo)
['__class__', '__delattr__', '__dict__', '__doc__', '__format__',
'__getattribute__', '__hash__', '__init__', '__module__', '__new__',
'__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__',
'__str__', '__subclasshook__', '__weakref__', 'another_value', 'value']
获得属性名称后,您可以使用getattr()
函数获取每个属性:
>>> getattr(foo, 'value')
42
要获取所有这些内容,您可以使用list comprehensions:
>>> [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]
最后,您可以找到您在某些属性上设置的值。
但是,此列表也包含方法。记住它们也是属性。在这种情况下,我们可以使列表理解避免可调用的attrbutes:
>>> [attrname for attrname in dir(foo) if not callable(getattr(foo, attrname))]
['__dict__', '__doc__', '__module__', '__weakref__', 'another_value', 'value']
现在,获取实际值:
>>> [getattr(foo, attrname) for attrname in dir(foo)
... if not callable(getattr(foo, attrname))]
[{'another_value': 34, 'value': 42}, None, '__main__', None, 34, 42]
那里仍然存在一些奇怪的值,例如__dict__
,__doc__
等。它们是您可能想要忽略的一些东西。如果是这样,只需在列表理解中添加另一个标准:
>>> [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]
还有其他方法可以做这些事情。例如,您可以查看对象的__dict__
和__slots__
属性。但是,我发现我提出的方法对于初学者来说更清晰。
编辑还有两点。首先,cls solution非常好,因为它建议您查看inspect
module。
此外,您可能希望同时获取属性的名称和值。你可以生成一个元组列表:
>>> [(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()功能做得更好。
>>> import inspect
>>> inspect.getmembers(foo)
[('__class__', <class '__main__.Foo'>),
# ... Lots of stuff ...
('another_value', 34), ('value', 42)]
要删除方法,只需避免使用callables:
>>> 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)]
(不幸的是,inspect.ismethod()
并没有像我预期的那样发挥作用。)
还有很多内部的东西,我们不能像我们对这些方法那样直接得到它们。列表理解无法再解决任何问题:
>>> [(name, value) for name, value in inspect.getmembers(foo, lambda attr: not callable(attr))
... if not name.startswith('__')]
[('another_value', 34), ('value', 42)]
Python是一种非常动态的语言,在某些情况下,此解决方案无法正常运行。考虑到可能有一个对象应该存储一个在某处使用的函数。函数是可调用对象,不会显示该属性。但是,逻辑上属性是要使用的数据。你应该记住这种东西。但是,我打赌你不会经常遇到这样的问题。
HTH
答案 2 :(得分:3)
这不是一个确切的等价物,但dir(self)
应该让你开始。