Как узнать, какие методы есть у объекта Python

Имеется ли простой способ получить список всех методов, имеющихся у этого объекта, для любого объекта Python?

Or,

если это невозможно, есть ли хотя бы простой способ проверить, есть ли у него конкретный метод, кроме простой проверки, возникает ли ошибка при вызове метода?


person Thomas Lötzer    schedule 29.08.2008    source источник
comment
Релевантно: stackoverflow.com/q/46033277/1959808   -  person Ioannis Filippidis    schedule 09.09.2017


Ответы (22)


Для многих объектов вы можете использовать этот код, заменив «объект» на интересующий вас объект:

object_methods = [method_name for method_name in dir(object)
                  if callable(getattr(object, method_name))]

Я обнаружил это на diveintopython.net (сейчас в архиве). Надеюсь, это даст дополнительную информацию!

Если вы получили AttributeError, вы можете использовать это вместо:

getattr( не терпит абстрактных виртуальных подклассов python3.6 в стиле панд. Этот код делает то же, что и выше, и игнорирует исключения.

import pandas as pd
df = pd.DataFrame([[10, 20, 30], [100, 200, 300]],
                  columns=['foo', 'bar', 'baz'])
def get_methods(object, spacing=20):
  methodList = []
  for method_name in dir(object):
    try:
        if callable(getattr(object, method_name)):
            methodList.append(str(method_name))
    except:
        methodList.append(str(method_name))
  processFunc = (lambda s: ' '.join(s.split())) or (lambda s: s)
  for method in methodList:
    try:
        print(str(method.ljust(spacing)) + ' ' +
              processFunc(str(getattr(object, method).__doc__)[0:90]))
    except:
        print(method.ljust(spacing) + ' ' + ' getattr() failed')

get_methods(df['foo'])
person ljs    schedule 29.08.2008
comment
Я не уверен, чего вы здесь пытаетесь достичь, но наличие метода в этих трех местах для меня не имеет смысла. Замена объекта на интересующий вас объект вернет все вызываемые объекты для любого объекта с одним вызываемым объектом. Пожалуйста, помогите мне понять суть. - person Bruno Bronosky; 26.03.2013
comment
Возможно, вы имели в виду [getattr(obj, method) for method in dir(obj) if method==method_name and callable(getattr(obj, method_name))], который можно использовать как: 'obj = {' foo ':' bar '}; method_name = 'получить'; x = [getattr (obj, method) для метода в каталоге (obj) if method == method_name and callable (getattr (obj, method_name))]; ' а потом if(len(x)): x[0]('foo') ... Я знаю, что на одной строке это действительно неприятно, но в комментариях нельзя переносить строки - person Bruno Bronosky; 26.03.2013
comment
@RichardBronosky, для вас это может не иметь никакого смысла, но это работает. - person jwg; 02.09.2014
comment
Это понимание списка, возвращающее список методов, где метод - это элемент в списке, возвращаемом dir (object), и где каждый метод добавляется в список только в том случае, если getattr (object, method) возвращает вызываемый объект. - person Mnebuerquo; 13.09.2014
comment
Как именно вы это используете? Сказать, распечатать список методов. - person marsh; 20.08.2015
comment
@marsh Чтобы распечатать методы: print [method for method in dir(object) if callable(getattr(object, method))]. - person Orienteerix; 29.10.2015
comment
Я получаю AttributeError: module 'pandas.core.common' has no attribute 'AbstractMethodError', когда пытаюсь запустить это. Подробности см. На странице stackoverflow.com/q/54713287/9677043. - person Karl Baker; 15.02.2019
comment
не работает для объекта фрейма данных pandas в python 3.6. - person Stefan Karlsson; 25.07.2019
comment
Чтобы исключить Dunder методы: [ m for m in dir(object) if not m.startswith('__')] - person John; 15.11.2019
comment
Другой способ использования фильтра: print(list(filter(lambda x: x[0] != '_' and callable(getattr(obj, x)), dir(obj)))) - person Paulo Buchsbaum; 06.02.2020
comment
Хотя такие вещи не распространены, это вернет вызываемые атрибуты экземпляра, которые не являются методами. Метод является результатом вызова атрибута class из экземпляра. Кроме того, dir не является надежным способом получить все атрибуты объекта; наиболее важно то, что класс может определить, что возвращает dir, переопределив __dir__. - person chepner; 28.01.2021

Вы можете использовать встроенную функцию dir(), чтобы получить список всех атрибутов, которые имеет модуль. Попробуйте это в командной строке, чтобы увидеть, как это работает.

>>> import moduleName
>>> dir(moduleName)

Кроме того, вы можете использовать функцию hasattr(module_name, "attr_name"), чтобы узнать, есть ли у модуля определенный атрибут.

Дополнительную информацию см. В Руководстве по интроспекции Python.

person Bill the Lizard    schedule 29.08.2008
comment
hasattr помог моему варианту использования определить, имеет ли объект python конкретную переменную или метод-член. - person Akshay; 13.02.2017
comment
Я не уверен, почему это решение не получило достаточно голосов. Это кратко и точно. - person Prasad Raghavendra; 25.05.2020
comment
поскольку dir () возвращает список, мы можем использовать 'attrib_name' in dir(moduleName) , чтобы узнать, есть ли у модуля определенный атрибут. - person Arvind Reddy; 17.06.2021

Самый простой способ - использовать dir(objectname). Он отобразит все методы, доступные для этого объекта. Классный трюк.

person Pawan Kumar    schedule 20.11.2013
comment
Он также отображает атрибуты объекта, поэтому, если вы хотите специально найти методы, это не сработает. - person eric; 09.12.2017
comment
да. Согласовано. Но мне неизвестен какой-либо другой способ получить только список методов. Может быть, лучше всего получить список атрибутов и методов, а затем использовать ‹hasattr (object, method_name›) для дальнейшей фильтрации? - person Pawan Kumar; 10.12.2017
comment
@neuronet, я пытаюсь запустить принятый ответ, но получаю AttributeError: module 'pandas.core.common' has no attribute 'AbstractMethodError'. Любые идеи? См. Подробности на stackoverflow.com/q/54713287/9677043. +1 к @Pawan Kumar b / c ответ работает, а к @ljs за обещание отфильтрованного списка только методов. - person Karl Baker; 15.02.2019

Я считаю, что вам нужно что-то вроде этого:

список атрибутов объекта

Эту работу может выполнить встроенная функция dir().

Взято из help(dir) вывода вашей оболочки Python:

реж (...)

dir([object]) -> list of strings

Если вызывается без аргумента, вернуть имена в текущей области.

В противном случае верните отсортированный по алфавиту список имен, содержащих (некоторые из) атрибутов данного объекта, и атрибутов, доступных из него.

Если объект предоставляет метод с именем __dir__, он будет использован; в противном случае используется логика dir () по умолчанию, которая возвращает:

  • для объекта модуля: атрибуты модуля.
  • для объекта класса: его атрибуты и рекурсивно атрибуты его баз.
  • для любого другого объекта: его атрибуты, атрибуты его класса и рекурсивно атрибуты базовых классов его класса.

Например:

$ python
Python 2.7.6 (default, Jun 22 2015, 17:58:13)
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.

>>> a = "I am a string"
>>>
>>> type(a)
<class 'str'>
>>>
>>> dir(a)
['__add__', '__class__', '__contains__', '__delattr__', '__doc__',
'__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__',
'__getnewargs__', '__getslice__', '__gt__', '__hash__', '__init__',
'__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__',
'__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__',
'__setattr__', '__sizeof__', '__str__', '__subclasshook__',
'_formatter_field_name_split', '_formatter_parser', 'capitalize',
'center', 'count', 'decode', 'encode', 'endswith', 'expandtabs', 'find',
'format', 'index', 'isalnum', 'isalpha', 'isdigit', 'islower', 'isspace',
'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'partition',
'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip',
'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title',
'translate', 'upper', 'zfill']
person ivanleoncz    schedule 26.05.2016

Чтобы проверить, есть ли у него конкретный метод:

hasattr(object,"method")
person Community    schedule 29.08.2008
comment
поскольку OP ищет метод, а не только атрибут, я думаю, вы хотите пойти еще дальше: if hasattr(obj,method) and callable(getattr(obj,method)): - person Bruno Bronosky; 26.03.2013

Помимо более прямых ответов, было бы упущением, если бы я не упомянул IPython.

Нажмите Tab, чтобы увидеть доступные методы с автозаполнением.

И как только вы найдете метод, попробуйте:

help(object.method)

чтобы увидеть pydocs, подпись метода и т. д.

Ах ... REPL.

person jmanning2k    schedule 29.08.2008

Если вам конкретно нужны методы, вам следует использовать inspect .ismethod.

Для названий методов:

import inspect
method_names = [attr for attr in dir(self) if inspect.ismethod(getattr(self, attr))]

Для самих методов:

import inspect
methods = [member for member in [getattr(self, attr) for attr in dir(self)] if inspect.ismethod(member)]

Иногда может оказаться полезным inspect.isroutine (для встроенных модулей C расширения, Cython без "привязки" директивы компилятора).

person paulmelnikow    schedule 29.01.2015
comment
Разве вам не следует использовать inspect.getmembers вместо dir в понимание списка? - person Boris; 23.04.2020
comment
Да, кажется, лучше! - person paulmelnikow; 24.04.2020

Самый простой способ получить список методов любого объекта - использовать команду help().

%help(object)

В нем будут перечислены все доступные / важные методы, связанные с этим объектом.

Например:

help(str)
person Paritosh Vyas    schedule 26.04.2018
comment
Что делает % в первом примере? Это не работает в моем Python 2.7. - person Scorchio; 25.07.2019
comment
@Scorchio Я использовал% в качестве подсказки вместо ››› для python. Вы можете удалить% перед запуском команды. - person Paritosh Vyas; 25.09.2019

Откройте оболочку Bash (Ctrl + Alt + T в Ubuntu). Запустите в нем оболочку Python 3. Создайте объект для наблюдения за методами. Просто добавьте точку после нее и дважды нажмите Tab, и вы увидите что-то вроде этого:

user@note:~$ python3
Python 3.4.3 (default, Nov 17 2016, 01:08:31)
[GCC 4.8.4] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import readline
>>> readline.parse_and_bind("tab: complete")
>>> s = "Any object. Now it's a string"
>>> s. # here tab should be pressed twice
s.__add__(           s.__rmod__(          s.istitle(
s.__class__(         s.__rmul__(          s.isupper(
s.__contains__(      s.__setattr__(       s.join(
s.__delattr__(       s.__sizeof__(        s.ljust(
s.__dir__(           s.__str__(           s.lower(
s.__doc__            s.__subclasshook__(  s.lstrip(
s.__eq__(            s.capitalize(        s.maketrans(
s.__format__(        s.casefold(          s.partition(
s.__ge__(            s.center(            s.replace(
s.__getattribute__(  s.count(             s.rfind(
s.__getitem__(       s.encode(            s.rindex(
s.__getnewargs__(    s.endswith(          s.rjust(
s.__gt__(            s.expandtabs(        s.rpartition(
s.__hash__(          s.find(              s.rsplit(
s.__init__(          s.format(            s.rstrip(
s.__iter__(          s.format_map(        s.split(
s.__le__(            s.index(             s.splitlines(
s.__len__(           s.isalnum(           s.startswith(
s.__lt__(            s.isalpha(           s.strip(
s.__mod__(           s.isdecimal(         s.swapcase(
s.__mul__(           s.isdigit(           s.title(
s.__ne__(            s.isidentifier(      s.translate(
s.__new__(           s.islower(           s.upper(
s.__reduce__(        s.isnumeric(         s.zfill(
s.__reduce_ex__(     s.isprintable(
s.__repr__(          s.isspace(
person Valery Ramusik    schedule 15.11.2017
comment
Пока мы говорим о подобных обходных путях, я добавлю, что вы также можете запустить ipython, начать вводить объект и нажать tab, и это тоже сработает. Никаких настроек чтения не требуется - person Max Coplan; 29.07.2019
comment
@MaxCoplan Я добавил обходной путь в код для случаев, когда завершение табуляции не включено по умолчанию - person Valery Ramusik; 30.07.2019

Проблема со всеми указанными здесь методами заключается в том, что вы не можете быть уверенным, что метод не существует.

В Python вы можете перехватывать вызов точки через __getattr__ и __getattribute__, что позволяет создать метод во время выполнения.

Пример:

class MoreMethod(object):
    def some_method(self, x):
        return x
    def __getattr__(self, *args):
        return lambda x: x*2

Если вы его выполните, вы можете вызвать несуществующие методы в словаре объектов ...

>>> o = MoreMethod()
>>> o.some_method(5)
5
>>> dir(o)
['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattr__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'some_method']
>>> o.i_dont_care_of_the_name(5)
10

Вот почему вы используете парадигмы Проще просить прощения, чем разрешения в Python.

person Cld    schedule 09.12.2014

Предположим, у нас есть Python obj. Затем, чтобы увидеть все имеющиеся у него методы, в том числе окруженные __ (магические методы):

print(dir(obj))

Чтобы увидеть только методы, доступные через инфиксную (точечную) нотацию, нужно:

[m for m in dir(obj) if not m.startswith('__')]
person Sergey Bushmanov    schedule 07.12.2020

Нет надежного способа перечислить все методы объекта. dir(object) обычно бывает полезным, но в некоторых случаях он может не перечислять все методы. Согласно dir() документации: «С аргументом, <сильный > попытаться вернуть список допустимых атрибутов для этого объекта "

Проверка того, существует ли метод, может быть выполнена callable(getattr(object, method)), как уже упоминалось там.

person aver    schedule 16.09.2015

import moduleName
for x in dir(moduleName):
    print(x)

Это должно работать :)

person The Mob    schedule 22.11.2019

Можно создать getAttrs функцию, которая будет возвращать имена вызываемых свойств объекта.

def getAttrs(object):
  return filter(lambda m: callable(getattr(object, m)), dir(object))

print getAttrs('Foo bar'.split(' '))

Это вернется

['__add__', '__class__', '__contains__', '__delattr__', '__delitem__',
 '__delslice__', '__eq__', '__format__', '__ge__', '__getattribute__', 
 '__getitem__', '__getslice__', '__gt__', '__iadd__', '__imul__', '__init__', 
 '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', 
 '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', 
 '__setattr__', '__setitem__', '__setslice__', '__sizeof__', '__str__', 
 '__subclasshook__', 'append', 'count', 'extend', 'index', 'insert', 'pop', 
 'remove', 'reverse', 'sort']
person james_womack    schedule 24.04.2015

Возьмите список как объект

obj = []

list(filter(lambda x:callable(getattr(obj,x)),obj.__dir__()))

Ты получаешь:

['__add__',
 '__class__',
 '__contains__',
 '__delattr__',
 '__delitem__',
 '__dir__',
 '__eq__',
 '__format__',
 '__ge__',
 '__getattribute__',
 '__getitem__',
 '__gt__',
 '__iadd__',
 '__imul__',
 '__init__',
 '__init_subclass__',
 '__iter__',
 '__le__',
 '__len__',
 '__lt__',
 '__mul__',
 '__ne__',
 '__new__',
 '__reduce__',
 '__reduce_ex__',
 '__repr__',
 '__reversed__',
 '__rmul__',
 '__setattr__',
 '__setitem__',
 '__sizeof__',
 '__str__',
 '__subclasshook__',
 'append',
 'clear',
 'copy',
 'count',
 'extend',
 'index',
 'insert',
 'pop',
 'remove',
 'reverse',
 'sort']
person Mahdi Ghelichi    schedule 16.01.2018

Для поиска определенного метода во всем модуле

for method in dir(module) :
  if "keyword_of_methode" in method :
   print(method, end="\n")
person Simon PII    schedule 09.03.2018

... есть хотя бы простой способ проверить, есть ли у него конкретный метод, кроме простой проверки, возникает ли ошибка при вызове метода

Хотя проще просить прощения, чем разрешения, безусловно, питонический путь, вы можете искать:

d={'foo':'bar', 'spam':'eggs'}
if 'get' in dir(d):
    d.get('foo')
# OUT: 'bar'
person Bruno Bronosky    schedule 26.03.2013

Вы можете использовать dir (), который предопределен в Python.

import module_name
dir(module_name)

Вы также можете передать объект в dir () как

dir(object_name)

Если объект является объектом предопределенного класса, такого как int, str и т. Д., Он отображает методы в нем (вы можете знать эти методы как встроенные функции). Если этот объект создан для определенного пользователем класса, он отображает все методы, данные в этом классе.

person Sanmitha Sadhishkumar    schedule 19.08.2020

Я выполнил следующую функцию (get_object_functions), которая получает объект (object_) в качестве аргумента и возвращает список (functions), содержащий все методы (включая статические методы и методы класса), определенные в классе объекта :

def get_object_functions(object_):
    functions = [attr_name
                 for attr_name in dir(object_)
                 if str(type(getattr(object_,
                                     attr_name))) in ("<class 'function'>",
                                                      "<class 'method'>")]
    return functions

Ну, он просто проверяет, равно ли строковое представление типа атрибута класса "<class 'function'>" или "<class 'method'>", а затем включает этот атрибут в список functions, если это True.


Демо

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def introduce(self):
        print(f'My name is {self.name}')

    @staticmethod
    def say_hi():
        print('hi')

    @classmethod
    def reproduce(cls, name):
        return cls(name, 0)


person = Person('Rafael', 27)
print(get_object_functions(person))

Выход

['__init__', 'introduce', 'reproduce', 'say_hi']

Для более чистой версии кода: https://github.com/revliscano/utilities/blob/master/get_object_functions/object_functions_getter.py

person revliscano    schedule 27.08.2020

В большинстве случаев я хочу видеть определяемые пользователем методы и не хочу видеть встроенные атрибуты, начинающиеся с '__', если вы хотите, чтобы вы могли использовать следующий код:

object_methods = [method_name for method_name in dir(object) if callable(getattr(object, method_name)) and '__' not in method_name] 

Например, для этого класса:

class Person: 
    def __init__(self, name): 
        self.name = name 
    def print_name(self):
        print(self.name)

Над кодом будет напечатано: ['print_name']

person Dharma    schedule 21.07.2021

Если вы, например, используете shell plus, вы можете использовать это вместо:

>> MyObject??

таким образом, с "??" сразу после вашего объекта он покажет вам все атрибуты / методы, которые есть у класса.

person Nick Cuevas    schedule 13.04.2020
comment
Что такое shell plus? - person Peter Mortensen; 02.12.2020

Вот хороший лайнер (но он также получит атрибуты):

print(*dir(obj), sep='\n')
person Zack Plauché    schedule 23.05.2021