Во-первых, я бы подчеркнул, что в 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
Чтобы получить все из них, вы можете использовать список понимания :
>>> [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]
В конце вы можете найти значенияВы устанавливаете некоторые атрибуты.
Однако этот список также будет содержать методы.Помните, что они также являются атрибутами.В этом случае мы можем сделать так, чтобы наше понимание списка избегало вызываемых атрибутов:
>>> [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 действительно хорошо, потому что оно предлагает вам взглянуть на inspect
модуль .
Кроме того, вы можете получить как имя, так изначение атрибута.Вы можете получить его, создав список кортежей:
>>> [(attrname, getattr(foo, attrname)) for attrname in dir(foo)
... if not attrname.startswith('__') and
... not callable(getattr(foo, attrname))]
[('another_value', 34), ('value', 42)]
К счастью, функция inspect.getmembers () , предложенная cls, делает это лучше.
>>> import inspect
>>> inspect.getmembers(foo)
[('__class__', <class '__main__.Foo'>),
# ... Lots of stuff ...
('another_value', 34), ('value', 42)]
Чтобы удалить методы, просто избегайте вызовов:
>>> 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