Как получить полный список методов и атрибутов объектов?
dir(re.compile(pattern))
не возвращает шаблон как один из элементов списка. А именно, он возвращает:
['__copy__', '__deepcopy__', 'findall', 'finditer', 'match', 'scanner', 'search', 'split', 'sub', 'subn']
Согласно руководству, предполагается, что он содержит
имена атрибутов объекта, имена его атрибутов класса и рекурсивно атрибутов его класса.
В нем также говорится, что
Список не обязательно завершен.
Есть ли способ получить список полный? Я всегда предполагал, что dir возвращает полный список, но, по-видимому, он не...
Также: есть ли способ перечислять только атрибуты? Или только методы?
Изменить: это на самом деле ошибка в python → предположительно, она исправлена в ветке 3.0 (и, возможно, также в версии 2.6)
Ответы
Ответ 1
Для полного списка атрибутов короткий ответ: no. Проблема в том, что атрибуты фактически определяются как аргументы, принятые встроенной функцией getattr
. Так как пользователь может переопределить __getattr__
, внезапно разрешая любой атрибут, нет возможности генерировать этот список. Функция dir
возвращает ключи в атрибуте __dict__
, т.е. Все доступные атрибуты, если метод __getattr__
не переопределяется.
Во втором вопросе это не имеет смысла. На самом деле, методы являются атрибутами, подлежащими вызову, и ничего больше. Вы можете фильтровать вызываемые атрибуты и, используя модуль inspect
, определить методы, методы или функции класса.
Ответ 2
Вот почему новый метод __dir__()
был добавлен в python 2.6
см
Ответ 3
Вот практическое дополнение к ответам PierreBdR и Moe:
- для Python >= 2.6 и классов нового стиля, dir() кажется достаточно,
- для классов старого стиля, мы можем по крайней мере сделать то, что делает стандартный стандартный модуль для поддержки завершения вкладки: в добавив к dir()
, найдите __class__
- и затем перейдите к его __bases__
:
# code borrowed from the rlcompleter module
# tested under Python 2.6 ( sys.version = '2.6.5 (r265:79063, Apr 16 2010, 13:09:56) \n[GCC 4.4.3]' )
# or: from rlcompleter import get_class_members
def get_class_members(klass):
ret = dir(klass)
if hasattr(klass,'__bases__'):
for base in klass.__bases__:
ret = ret + get_class_members(base)
return ret
def uniq( seq ):
""" the 'set()' way ( use dict when there no set ) """
return list(set(seq))
def get_object_attrs( obj ):
# code borrowed from the rlcompleter module ( see the code for Completer::attr_matches() )
ret = dir( obj )
## if "__builtins__" in ret:
## ret.remove("__builtins__")
if hasattr( obj, '__class__'):
ret.append('__class__')
ret.extend( get_class_members(obj.__class__) )
ret = uniq( ret )
return ret
(Тестовый код и вывод удаляются для краткости, но в основном для объектов нового стиля мы, похоже, имеем те же результаты для get_object_attrs()
, что и для dir()
, а для классов старого стиля основное дополнение к dir()
кажется, что это атрибут __class__
))
Ответ 4
Вот как я это сделал, полезный только для простых пользовательских объектов, которым вы продолжаете добавлять атрибуты:
заданный объект obj, созданный с помощью obj = type("CustomObj",(object,),{})
, или просто:
class CustomObj(object):
pass
obj=CustomObject()
то для получения словаря только с настраиваемыми атрибутами, я делаю:
{key: value for key, value in self.__dict__.items() if not key.startswith("__")}