Как получить полный список методов и атрибутов объектов?

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, определить методы, методы или функции класса.

Ответ 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("__")}