Как перечислить все поля класса в Python (и без методов)?
Предположим, что o
- объект Python, и я хочу все поля o
без каких-либо методов или __stuff__
. Как это можно сделать?
Я пробовал такие вещи, как:
[f for f in dir(o) if not callable(f)]
[f for f in dir(o) if not inspect.ismethod(f)]
но они возвращают то же самое, что и dir(o)
, предположительно потому, что dir
дает список строк. Кроме того, такие вещи, как __class__
, будут возвращены сюда, даже если я получу это для работы.
Ответы
Ответ 1
Вы можете получить его с помощью атрибута __dict__
или встроенной vars
функции, которая является просто ярлыком:
>>> 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}
Есть только атрибуты объекта. Методов и атрибутов класса нет.
Ответ 2
Основной ответ: "вы не можете сделать это надежно". См. этот вопрос.
Вы можете получить приближение с помощью [attr for attr in dir(obj) if attr[:2] + attr[-2:] != '____' and not callable(getattr(obj,attr)]
.
Однако вы не должны полагаться на это, потому что:
Поскольку dir()
предоставляется в первую очередь как удобство для использования в интерактивном приглашении, он пытается предоставить интересный набор имен больше, чем пытается предоставить строго или последовательно определенный набор имен, и его подробное поведение может измениться через выпуски.
Другими словами, нет никакого канонического способа получить список "всех атрибутов объекта" (или "все методы объекта" ).
Если вы выполняете какое-то динамическое программирование, которое требует от вас повторения полей unknwon объекта, единственный надежный способ сделать это - реализовать собственный способ отслеживания этих полей. Например, вы можете использовать соглашение об именах атрибутов или специальный объект "поля" или, проще говоря, словарь.
Ответ 3
Это должно работать для вызовов:
[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('__')]
Ответ 4
Вы можете использовать встроенный метод vars()
Ответ 5
Вы можете перебирать атрибут __dict__
экземпляра и искать не-методы.
Например:
CALLABLES = (types.FunctionType, types.MethodType)
for key, value in A().__dict__.items():
if not isinstance(value, CALLABLES):
print key
Вывод:
foo
bar
Вы можете сделать это в одном выражении со списком:
print [key for key, value in A.__dict__.items()
if not isinstance(value, CALLABLES)]
Что бы напечатать ['foo', 'bar']
.