Нахождение каких методов у объекта Python


431

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

Или,

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


Ответы:


525

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

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']) 

3
Это понимание списка, возвращающее список методов, где метод - это элемент в списке, возвращаемый dir (объект), и где каждый метод добавляется в список, только если getattr (объект, метод) возвращает вызываемый объект.
Mnebuerquo

1
Как именно вы используете это? Сказать распечатать список методов.
болотный

13
@marsh Для печати методы: print [method for method in dir(object) if callable(getattr(object, method))].
Orienteerix

1
Я получаю, AttributeError: module 'pandas.core.common' has no attribute 'AbstractMethodError'когда я пытаюсь запустить это. Подробнее см. На stackoverflow.com/q/54713287/9677043 .
Карл Бейкер

1
не работает для объекта DataFrame Pandas в Python 3.6.
Стефан Карлссон

226

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

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

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

См. Руководство по интроспекции Python для получения дополнительной информации.


hasattrпомог мой вариант использования, чтобы найти, есть ли у объекта Python конкретная переменная-член или метод.
Акшай

Я не уверен, почему за это решение недостаточно проголосовали. Это кратко и точно.
Прасад Рагхавендра

93

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


3
Он также отображает атрибуты объекта, поэтому, если вы хотите специально найти методы, он не будет работать.
Эрик

Да. Согласовано. Но я не знаю какой-либо другой техники, чтобы получить только список методов. Может быть, лучшая идея - получить список атрибутов и методов, а затем использовать <hasattr (object, "method_name"> для дальнейшей его фильтрации?
Pawan Kumar

1
@neuronet, я пытаюсь запустить принятый ответ, но получаю ответ AttributeError: module 'pandas.core.common' has no attribute 'AbstractMethodError'. Любые идеи? См. Deets по адресу stackoverflow.com/q/54713287/9677043 . +1 к @Pawan Kumar b / c ответ работает, а к @ljs - обещание отфильтрованного списка только методов.
Карл Бейкер

30

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

hasattr(object,"method")

14
Так как ОП ищет метод, а не только атрибут и атрибут, я думаю, вы хотите пойти еще дальше с:if hasattr(obj,method) and callable(getattr(obj,method)):
Бруно Броноски,

28

Я считаю, что вы хотите что-то вроде этого:

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

По моему скромному мнению, встроенная функция 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']

Пока я проверял вашу проблему, я решил продемонстрировать свой ход мыслей с лучшим форматированием вывода dir().

dir_attributes.py (Python 2.7.6)

#!/usr/bin/python
""" Demonstrates the usage of dir(), with better output. """

__author__ = "ivanleoncz"

obj = "I am a string."
count = 0

print "\nObject Data: %s" % obj
print "Object Type: %s\n" % type(obj)

for method in dir(obj):
    # the comma at the end of the print, makes it printing 
    # in the same line, 4 times (count)
    print "| {0: <20}".format(method),
    count += 1
    if count == 4:
        count = 0
        print

dir_attributes.py (Python 3.4.3)

#!/usr/bin/python3
""" Demonstrates the usage of dir(), with better output. """

__author__ = "ivanleoncz"

obj = "I am a string."
count = 0

print("\nObject Data: ", obj)
print("Object Type: ", type(obj),"\n")

for method in dir(obj):
    # the end=" " at the end of the print statement, 
    # makes it printing in the same line, 4 times (count)
    print("|    {:20}".format(method), end=" ")
    count += 1
    if count == 4:
        count = 0
        print("")

Надеюсь, что я внес свой вклад :).


1
Внесенный? Ваш ответ сработал для меня в Python 2.7.12, так что, черт возьми, да!
gsamaras

23

Помимо более прямых ответов, я был бы упущен, если бы не упомянул iPython . Нажмите «Tab», чтобы увидеть доступные методы с автозаполнением.

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

help(object.method) 

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

Ааа ... REPL .


12

Если вы конкретно хотите методы , вы должны использовать 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 без директивы компилятора «binding»).


Разве вы не должны использовать inspect.getmembersвместо использования dirв понимании списка?
Борис

Да, это кажется лучше!
Паульмельников

11

Откройте командную оболочку (Ctrl + Alt + T в Ubuntu). Запустите в нем оболочку python3. Создать объект для наблюдения за методами. Просто добавьте точку после нее и дважды нажмите «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(           

1
Пока мы говорим об обходных путях, подобных этому, я добавлю, что вы также можете запустить ipython, начать набирать объект и нажать, tabи он тоже будет работать. Не требуется никаких настроек readline
Макс

1
@MaxCoplan Я добавил обходной путь в коде для случаев, когда завершение табуляции не включено по умолчанию
Валерий Рамусик

8

Проблема всех указанных здесь методов заключается в том, что вы НЕ МОЖЕТЕ быть уверены, что метод не существует.

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

Exemple:

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.


6

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

%help(object)

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

Например:

help(str)

Что делает %в первом примере? Это не работает в моем Python 2.7.
Скорпион

@ Scorchio Я использовал "%" в качестве приглашения вместо ">>>" для Python. Вы можете удалить% до запуска команды.
Паритош Вьяс


1

Можно создать 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']

1

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

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


1

Взять список в качестве объекта

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']

0

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

В то время как « Проще просить прощения, чем разрешения » - это, конечно, путь Pythonic, возможно, то, что вы ищете:

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

0

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

for method in dir(module) :
  if "keyword_of_methode" in method :
   print(method, end="\n")

-1

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

>> MyObject??

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.