Menemukan metode apa yang dimiliki objek Python

430

Diberikan objek Python dalam bentuk apa pun, adakah cara mudah untuk mendapatkan daftar semua metode yang dimiliki objek ini?

Atau,

jika ini tidak memungkinkan, adakah setidaknya cara mudah untuk memeriksa apakah ia memiliki metode tertentu selain hanya memeriksa jika kesalahan terjadi ketika metode dipanggil?

Thomas Lötzer
sumber
Relevan: stackoverflow.com/q/46033277/1959808
Ioannis Filippidis

Jawaban:

524

Untuk banyak objek , Anda dapat menggunakan kode ini, menggantikan 'objek' dengan objek yang Anda minati:

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

Saya menemukannya di diveintopython.net (Sekarang diarsipkan). Semoga itu memberikan detail lebih lanjut!

Jika Anda mendapatkan AttributeError, Anda dapat menggunakan ini sebagai gantinya :

getattr(tidak toleran dengan gaya panda python3.6 abstrak virtual sub-kelas. Kode ini melakukan hal yang sama seperti di atas dan mengabaikan pengecualian.

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']) 
ls
sumber
3
Ini adalah pemahaman daftar, mengembalikan daftar metode di mana metode adalah item dalam daftar yang dikembalikan oleh dir (objek), dan di mana setiap metode ditambahkan ke daftar hanya jika getattr (objek, metode) mengembalikan callable.
Mnebuerquo
1
Bagaimana tepatnya Anda menggunakan ini? Untuk mengatakan, cetak daftar metode.
marsh
12
@marsh Untuk mencetak metode: print [method for method in dir(object) if callable(getattr(object, method))].
Orienteerix
1
Saya mendapatkan AttributeError: module 'pandas.core.common' has no attribute 'AbstractMethodError'ketika saya mencoba menjalankan ini. Lihat detail di stackoverflow.com/q/54713287/9677043 .
Karl Baker
1
tidak bekerja untuk objek dataframe panda di python 3.6.
Stefan Karlsson
226

Anda dapat menggunakan dir()fungsi bawaan untuk mendapatkan daftar semua atribut yang dimiliki modul. Coba ini di baris perintah untuk melihat cara kerjanya.

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

Anda juga dapat menggunakan hasattr(module_name, "attr_name")fungsi ini untuk mengetahui apakah suatu modul memiliki atribut tertentu.

Lihat panduan introspeksi Python untuk informasi lebih lanjut.

Bill the Lizard
sumber
hasattrmembantu kasus penggunaan saya untuk menemukan apakah objek python memiliki variabel anggota tertentu atau metode.
Akshay
Saya tidak yakin mengapa solusi ini tidak cukup ter-upgrade. Ini singkat dan akurat.
Prasad Raghavendra
93

Metode paling sederhana adalah menggunakan dir(objectname). Ini akan menampilkan semua metode yang tersedia untuk objek itu. Trik keren.

Pawan Kumar
sumber
3
Ini juga menampilkan atribut objek, jadi jika Anda ingin secara khusus menemukan metode, itu tidak akan berfungsi.
eric
Iya. Sepakat. Tapi, saya tidak mengetahui teknik lain untuk hanya mendapatkan daftar metode. Mungkin ide terbaik adalah untuk mendapatkan daftar atribut dan metode dan kemudian menggunakan <hasattr (objek, "method_name"> untuk lebih memfilternya?
Pawan Kumar
1
@neuronet, saya mencoba menjalankan jawaban yang diterima tetapi mendapatkan AttributeError: module 'pandas.core.common' has no attribute 'AbstractMethodError'. Ada ide? Lihat deet di stackoverflow.com/q/54713287/9677043 . +1 ke @Pawan Kumar b / c jawabannya berfungsi, dan ke @ ljs untuk janji daftar yang disaring dari hanya metode.
Karl Baker
30

Untuk memeriksa apakah ia memiliki metode tertentu:

hasattr(object,"method")
Bill the Lizard
sumber
14
karena OP sedang mencari metode dan bukan hanya atribut, saya pikir Anda ingin melangkah lebih jauh dengan:if hasattr(obj,method) and callable(getattr(obj,method)):
Bruno Bronosky
28

Saya percaya bahwa yang Anda inginkan adalah sesuatu seperti ini:

daftar atribut dari suatu objek

Menurut pendapat saya yang sederhana, fungsi bawaan dir()dapat melakukan pekerjaan ini untuk Anda. Diambil dari help(dir)output di Shell Python Anda:

dir (...)

dir([object]) -> list of strings

Jika dipanggil tanpa argumen, kembalikan nama dalam cakupan saat ini.

Selain itu, kembalikan daftar nama yang disusun menurut abjad yang terdiri dari (beberapa) atribut dari objek yang diberikan, dan atribut yang dapat dijangkau darinya.

Jika objek memasok metode yang bernama __dir__, itu akan digunakan; jika tidak, logika dir () default digunakan dan mengembalikan:

  • untuk objek modul: atribut modul.
  • untuk objek kelas: atributnya, dan secara rekursif atribut basisnya.
  • untuk objek lain: atributnya, atribut kelasnya, dan secara rekursif atribut kelas dasar kelasnya.

Sebagai contoh:

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

Ketika saya sedang memeriksa masalah Anda, saya memutuskan untuk menunjukkan pemikiran saya, dengan format yang lebih baik dari hasil 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("")

Semoga saya berkontribusi :).

ivanleoncz
sumber
1
Berkontribusi? Jawaban Anda berhasil bagi saya dengan Python 2.7.12, jadi ya ampun!
gsamaras
23

Di atas jawaban yang lebih langsung, saya akan lalai jika saya tidak menyebutkan iPython . Tekan 'tab' untuk melihat metode yang tersedia, dengan pelengkapan otomatis.

Dan setelah Anda menemukan metode, coba:

help(object.method) 

untuk melihat pydocs, tanda tangan metode, dll.

Ahh ... REPL .

jmanning2k
sumber
12

Jika Anda secara khusus menginginkan metode , Anda harus menggunakan metode inspect.ismet .

Untuk nama metode:

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

Untuk metode itu sendiri:

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

Terkadang inspect.isroutinedapat berguna juga (untuk built-in, ekstensi C, Cython tanpa direktif kompilasi "mengikat").

paulmelnikow
sumber
Bukankah seharusnya Anda menggunakan inspect.getmembersalih-alih menggunakan dirdalam pemahaman daftar?
Boris
Ya, itu sepertinya lebih baik!
paulmelnikow
11

Buka bash shell (ctrl + alt + T di Ubuntu). Mulai shell python3 di dalamnya. Buat objek untuk mengamati metode. Tambahkan saja titik setelahnya dan tekan dua kali "tab" dan Anda akan melihat sesuatu seperti itu:

 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
sumber
1
Sementara kita berbicara tentang pemecahan masalah seperti ini, saya akan menambahkan bahwa Anda juga dapat menjalankan ipython, mulai mengetik objek dan tekan tabdan itu akan berhasil juga. Tidak diperlukan pengaturan readline
Max Coplan
1
@ MaxCoplan Saya telah menambahkan solusi dalam kode untuk kasus-kasus di mana penyelesaian tab tidak diaktifkan secara default
Valery Ramusik
8

Masalah dengan semua metode yang ditunjukkan di sini adalah bahwa Anda TIDAK BISA yakin bahwa metode tidak ada.

Dengan Python Anda dapat memotong titik yang memanggil melalui __getattr__dan__getattribute__ , memungkinkan untuk membuat metode "saat runtime"

Contoh:

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

Jika Anda menjalankannya, Anda dapat memanggil metode yang tidak ada di kamus objek ...

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

Dan itu sebabnya Anda menggunakan Lebih Mudah untuk meminta pengampunan daripada paradigma izin di Python.

Cld
sumber
6

Cara paling sederhana untuk mendapatkan daftar metode dari objek apa pun adalah dengan menggunakan help()perintah.

%help(object)

Ini akan mencantumkan semua metode yang tersedia / penting yang terkait dengan objek itu.

Sebagai contoh:

help(str)
Paritosh Vyas
sumber
Apa yang %dilakukan pada contoh pertama? Itu tidak berfungsi di Python 2.7 saya.
Scorchio
@ Scorchio Saya telah menggunakan "%" sebagai prompt, bukan ">>>" untuk python. Anda dapat menghapus% sebelum menjalankan perintah.
Paritosh Vyas
3
import moduleName
for x in dir(moduleName):
print(x)

Ini seharusnya bekerja :)

Massa
sumber
1

Seseorang dapat membuat getAttrsfungsi yang akan mengembalikan nama properti yang bisa dipanggil objek

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

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

Itu akan kembali

['__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
sumber
1

Tidak ada cara yang dapat diandalkan untuk mendaftar semua metode objek. dir(object)biasanya bermanfaat, tetapi dalam beberapa kasus mungkin tidak mencantumkan semua metode. Menurut dir()dokumentasi : "Dengan argumen, cobalah untuk mengembalikan daftar atribut yang valid untuk objek itu."

Memeriksa metode yang ada dapat dilakukan callable(getattr(object, method))seperti yang telah disebutkan di sana.

menegaskan
sumber
1

Ambil daftar sebagai objek

obj = []

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

Anda mendapatkan:

['__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
sumber
0

... adakah setidaknya cara mudah untuk memeriksa apakah ia memiliki metode tertentu selain hanya memeriksa jika terjadi kesalahan ketika metode tersebut disebut

Meskipun " Lebih mudah meminta pengampunan daripada izin " tentu saja merupakan cara Pythonic, apa yang Anda cari mungkin:

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

Untuk mencari metode tertentu di seluruh modul

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

Jika Anda, misalnya, menggunakan shell plus Anda dapat menggunakan ini sebagai gantinya:

>> MyObject??

seperti itu, dengan '??' tepat setelah objek Anda, itu akan menunjukkan semua atribut / metode yang dimiliki kelas.

Nick Cuevas
sumber