Trovare quali metodi ha un oggetto Python
-
09-06-2019 - |
Domanda
Dato un oggetto Python di qualsiasi tipo, esiste un modo semplice per ottenere l'elenco di tutti i metodi di cui dispone questo oggetto?
O,
se ciò non è possibile, esiste almeno un modo semplice per verificare se ha un metodo particolare diverso dal semplice controllo se si verifica un errore quando viene chiamato il metodo?
Soluzione
Sembra che tu possa usare questo codice, sostituendo 'oggetto' con l'oggetto che ti interessa:
object_methods = [method_name for method_name in dir(object)
if callable(getattr(object, method_name))]
L'ho scoperto a questo sito.Si spera che ciò fornisca ulteriori dettagli!
Altri suggerimenti
Puoi usare quello integrato dir()
funzione per ottenere un elenco di tutti gli attributi di un modulo.Provalo dalla riga di comando per vedere come funziona.
>>> import moduleName
>>> dir(moduleName)
Inoltre, puoi utilizzare il file hasattr(module_name, "attr_name")
funzione per scoprire se un modulo ha un attributo specifico.
Vedi il Guida all'introspezione di Python per maggiori informazioni.
Il metodo più semplice è usare dir(objectname)
.Verranno visualizzati tutti i metodi disponibili per quell'oggetto.Bel trucco.
Per verificare se ha un metodo particolare:
hasattr(object,"method")
Credo che quello che vuoi sia qualcosa del genere:
un elenco di attributi di un oggetto
A mio modesto parere, la funzione integrata dir()
può fare questo lavoro per te.Preso da help(dir)
output sulla tua shell Python:
dir(...)
dir([object]) -> list of strings
Se chiamato senza argomento, restituisce i nomi nell'ambito corrente.
Altrimenti, restituisci un elenco in ordine alfabetico di nomi che comprendono (alcuni degli) attributi dell'oggetto dato e degli attributi raggiungibili da esso.
Se l'oggetto fornisce un metodo denominato
__dir__
, verrà utilizzato;altrimenti viene usata la logica predefinita dir() e restituisce:
- per un oggetto modulo:gli attributi del modulo.
- per un oggetto di classe:i suoi attributi e ricorsivamente gli attributi delle sue basi.
- per qualsiasi altro oggetto:i suoi attributi, gli attributi della sua classe, e ricorsivamente gli attributi delle classi base della sua classe.
Per esempio:
$ 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']
Mentre controllavo il tuo problema, ho deciso di dimostrare il mio pensiero, con una migliore formattazione dell'output di 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("")
Spero di aver contribuito :).
Oltre alle risposte più dirette, sarei negligente se non lo menzionassi iPython.Premi "scheda" per vedere i metodi disponibili, con completamento automatico.
E una volta trovato un metodo, prova:
help(object.method)
per vedere i pydocs, la firma del metodo, ecc.
Ahh... SOSTITUZIONE.
Se lo desideri specificatamente metodi, dovresti usare metodo.ispeziona.
Per i nomi dei metodi:
import inspect
method_names = [attr for attr in dir(self) if inspect.ismethod(getattr(self, attr))]
Per i metodi stessi:
import inspect
methods = [member for member in [getattr(self, attr) for attr in dir(self)] if inspect.ismethod(member)]
A volte inspect.isroutine
può essere utile anche (per built-in, estensioni C, Cython senza la direttiva del compilatore "binding").
Apri la shell bash (ctrl+alt+T su Ubuntu).Avvia la shell python3 al suo interno.Crea un oggetto di cui osservare i metodi.Basta aggiungere un punto dopo e premere due volte "tab" e vedrai qualcosa del genere:
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(
Il problema con tutti i metodi qui indicati è che NON PUOI essere sicuro che un metodo non esista.
In Python puoi intercettare il punto che chiama thru __getattr__
E __getattribute__
, rendendo possibile la creazione del metodo "in fase di esecuzione"
Esempio:
class MoreMethod(object):
def some_method(self, x):
return x
def __getattr__(self, *args):
return lambda x: x*2
Se lo esegui, puoi chiamare il metodo non esistente nel dizionario degli oggetti...
>>> 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
Ed è per questo che usi il È più facile chiedere perdono che permesso paradigmi in Python.
Il modo più semplice per ottenere l'elenco dei metodi di qualsiasi oggetto è utilizzare help()
comando.
%help(object)
Elencherà tutti i metodi disponibili/importanti associati a quell'oggetto.
Per esempio:
help(str)
Si può creare un getAttrs
funzione che restituirà i nomi delle proprietà richiamabili di un oggetto
def getAttrs(object):
return filter(lambda m: callable(getattr(object, m)), dir(object))
print getAttrs('Foo bar'.split(' '))
Tornerebbe
['__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']
Non esiste un modo affidabile per elencare tutti i metodi dell'oggetto. dir(object)
è solitamente utile, ma in alcuni casi potrebbe non elencare tutti i metodi.Secondo dir()
documentazione: "Con una discussione, tentativo per restituire un elenco di attributi validi per quell'oggetto."
È possibile verificare che il metodo esista callable(getattr(object, method))
come già accennato lì.
...esiste almeno un modo semplice per verificare se ha un metodo particolare oltre al semplice controllo se si verifica un errore quando viene chiamato il metodo
Mentre "È più facile chiedere perdono che permesso" è certamente il modo Pythonic, quello che stai cercando forse:
d={'foo':'bar', 'spam':'eggs'}
if 'get' in dir(d):
d.get('foo')
# OUT: 'bar'
Prendi una lista come oggetto
obj = []
list(filter(lambda x:callable(getattr(obj,x)),obj.__dir__()))
Ottieni:
['__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']
Per cercare un metodo specifico in un intero modulo
for method in dir(module) :
if "keyword_of_methode" in method :
print(method, end="\n")