Recherche des méthodes d'un objet Python

431

Étant donné un objet Python de toute sorte, existe-t-il un moyen facile d'obtenir la liste de toutes les méthodes dont cet objet dispose?

Ou,

si cela n'est pas possible, existe-t-il au moins un moyen facile de vérifier si elle a une méthode particulière autre que de simplement vérifier si une erreur se produit lors de l'appel de la méthode?

Thomas Lötzer
la source
Pertinent: stackoverflow.com/q/46033277/1959808
Ioannis Filippidis

Réponses:

525

Pour de nombreux objets , vous pouvez utiliser ce code, en remplaçant «objet» par l'objet qui vous intéresse:

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

Je l'ai découvert sur diveintopython.net (maintenant archivé). J'espère que cela devrait fournir plus de détails!

Si vous obtenez un AttributeError, vous pouvez l'utiliser à la place :

getattr(est intolérant aux sous-classes virtuelles abstraites de style python3.6 pandas. Ce code fait la même chose que ci-dessus et ignore les exceptions.

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']) 
ljs
la source
3
Il s'agit d'une compréhension de liste, renvoyant une liste de méthodes où méthode est un élément de la liste renvoyé par dir (objet), et où chaque méthode n'est ajoutée à la liste que si getattr (objet, méthode) renvoie un appelable.
Mnebuerquo
1
Comment utilisez-vous exactement cela? Pour dire, imprimez une liste des méthodes.
marais
13
@marsh Pour imprimer les méthodes suivantes : print [method for method in dir(object) if callable(getattr(object, method))].
Orienteerix
1
J'obtiens un AttributeError: module 'pandas.core.common' has no attribute 'AbstractMethodError'quand j'essaye d'exécuter ceci. Voir les détails sur stackoverflow.com/q/54713287/9677043 .
Karl Baker
1
ne fonctionne pas pour l'objet pandas dataframe en python 3.6.
Stefan Karlsson
226

Vous pouvez utiliser la dir()fonction intégrée pour obtenir une liste de tous les attributs d'un module. Essayez ceci sur la ligne de commande pour voir comment cela fonctionne.

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

En outre, vous pouvez utiliser la hasattr(module_name, "attr_name")fonction pour savoir si un module a un attribut spécifique.

Voir le Guide sur l'introspection Python pour plus d'informations.

Bill le lézard
la source
hasattraidé mon cas d'utilisation pour trouver si l'objet python a une variable ou une méthode membre particulière.
Akshay
Je ne sais pas pourquoi cette solution n'est pas suffisamment votée. C'est concis et précis.
Prasad Raghavendra
93

La méthode la plus simple est d'utiliser dir(objectname). Il affichera toutes les méthodes disponibles pour cet objet. Truc cool.

Pawan Kumar
la source
3
Il affiche également les attributs de l'objet, donc si vous souhaitez rechercher spécifiquement des méthodes, cela ne fonctionnera pas.
Eric
Oui. D'accord. Mais, je ne connais aucune autre technique pour obtenir uniquement la liste des méthodes. Peut-être que la meilleure idée est d'obtenir la liste des attributs et des méthodes, puis d'utiliser <hasattr (object, "method_name"> pour le filtrer davantage?
Pawan Kumar
1
@neuronet, j'essaie d'exécuter la réponse acceptée mais j'obtiens un AttributeError: module 'pandas.core.common' has no attribute 'AbstractMethodError'. Des idées? Voir les détails sur stackoverflow.com/q/54713287/9677043 . +1 à @Pawan Kumar b / c la réponse fonctionne, et à @ljs pour la promesse d'une liste filtrée des méthodes uniquement.
Karl Baker
30

Pour vérifier s'il a une méthode particulière:

hasattr(object,"method")
Bill le lézard
la source
14
puisque l'OP recherche une méthode et pas seulement et un attribut, je pense que vous voulez aller plus loin avec:if hasattr(obj,method) and callable(getattr(obj,method)):
Bruno Bronosky
28

Je crois que ce que vous voulez est quelque chose comme ça:

une liste d'attributs d'un objet

À mon humble avis, la fonction intégrée dir()peut faire ce travail pour vous. Extrait de la help(dir)sortie sur votre shell Python:

dir (...)

dir([object]) -> list of strings

S'il est appelé sans argument, retournez les noms dans la portée actuelle.

Sinon, retournez une liste alphabétique de noms comprenant (certains des) attributs de l'objet donné et des attributs accessibles à partir de celui-ci.

Si l'objet fournit une méthode nommée __dir__, elle sera utilisée; sinon la logique dir () par défaut est utilisée et retourne:

  • pour un objet module: les attributs du module.
  • pour un objet de classe: ses attributs, et récursivement les attributs de ses bases.
  • pour tout autre objet: ses attributs, les attributs de sa classe et récursivement les attributs des classes de base de sa classe.

Par exemple:

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

Alors que je vérifiais votre problème, j'ai décidé de montrer mon cheminement de pensée, avec un meilleur formatage de la sortie de 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("")

J'espère que j'ai contribué :).

ivanleoncz
la source
1
Contribué? Votre réponse a fonctionné pour moi dans Python 2.7.12, alors bon sang oui!
gsamaras
23

En plus des réponses plus directes, je m'en voudrais de ne pas mentionner iPython . Appuyez sur «tab» pour voir les méthodes disponibles, avec saisie semi-automatique.

Et une fois que vous avez trouvé une méthode, essayez:

help(object.method) 

pour voir les pydocs, la signature de méthode, etc.

Ahh ... REPL .

jmanning2k
la source
12

Si vous souhaitez spécifiquement des méthodes , vous devez utiliser inspect.ismethod .

Pour les noms de méthode:

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

Pour les méthodes elles-mêmes:

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

Parfois, cela inspect.isroutinepeut aussi être utile (pour les fonctions intégrées, les extensions C, Cython sans la directive du compilateur "contraignant").

paulmelnikow
la source
Ne devriez-vous pas utiliser inspect.getmembersau lieu d'utiliser dirdans une liste de compréhension?
Boris
Oui, ça semble mieux!
paulmelnikow
11

Ouvrez le shell bash (ctrl + alt + T sur Ubuntu). Démarrez le shell python3 dedans. Créer un objet pour observer les méthodes. Ajoutez simplement un point après et appuyez deux fois sur "tab" et vous verrez quelque chose comme ça:

 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(           
Valery Ramusik
la source
1
Pendant que nous parlons de solutions de contournement comme celle-ci, j'ajouterai que vous pouvez également exécuter ipython, commencer à taper l'objet et appuyer sur tabet cela fonctionnera également. Aucun paramètre de ligne de lecture nécessaire
Max Coplan
1
@MaxCoplan J'ai ajouté la solution de contournement dans le code pour les cas où la tabulation n'est pas activée par défaut
Valery Ramusik
8

Le problème avec toutes les méthodes indiquées ici est que vous NE POUVEZ PAS être sûr qu'une méthode n'existe pas.

En Python, vous pouvez intercepter le point appelant à travers __getattr__et __getattribute__, permettant de créer une méthode "lors de l'exécution"

Exemple:

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

Si vous l'exécutez, vous pouvez appeler une méthode non existante dans le dictionnaire d'objets ...

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

Et c'est pourquoi vous utilisez le plus simple pour demander pardon que les paradigmes d' autorisation en Python.

Cld
la source
6

La façon la plus simple d'obtenir la liste des méthodes de n'importe quel objet est d'utiliser la help()commande.

%help(object)

Il répertorie toutes les méthodes disponibles / importantes associées à cet objet.

Par exemple:

help(str)
Paritosh Vyas
la source
Que fait le %premier exemple? Cela ne fonctionne pas dans mon Python 2.7.
Scorchio
@Scorchio J'ai utilisé "%" comme invite à la place ">>>" pour python. Vous pouvez supprimer% avant d'exécuter la commande.
Paritosh Vyas
3
import moduleName
for x in dir(moduleName):
print(x)

Cela devrait fonctionner :)

La mafia
la source
1

On peut créer une getAttrsfonction qui renverra les noms des propriétés appelables d'un objet

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

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

Ça reviendrait

['__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']
james_womack
la source
1

Il n'existe aucun moyen fiable de répertorier toutes les méthodes des objets. dir(object)est généralement utile, mais dans certains cas, il peut ne pas répertorier toutes les méthodes. Selon la dir()documentation : "Avec un argument, essayez de renvoyer une liste d'attributs valides pour cet objet."

La vérification de l'existence de cette méthode peut être effectuée callable(getattr(object, method))comme indiqué précédemment.

aver
la source
1

Prendre une liste comme objet

obj = []

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

Vous obtenez:

['__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']
Mahdi Ghelichi
la source
0

... existe-t-il au moins un moyen facile de vérifier si elle a une méthode particulière autre que de simplement vérifier si une erreur se produit lors de l'appel de la méthode

Alors que " Plus facile de demander pardon que permission " est certainement la voie Pythonique, ce que vous recherchez peut-être:

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

Afin de rechercher une méthode spécifique dans un module entier

for method in dir(module) :
  if "keyword_of_methode" in method :
   print(method, end="\n")
Simon PII
la source
-1

Si vous utilisez, par exemple, shell plus, vous pouvez l'utiliser à la place:

>> MyObject??

de cette façon, avec le "??" juste après votre objet, il vous montrera tous les attributs / méthodes de la classe.

Nick Cuevas
la source