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?


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

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.


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.


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

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é :).


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 .


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").


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(           

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.


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)

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


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

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.


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

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'

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

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

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.