Bagaimana cara melihat ke dalam objek Python?


291

Saya mulai membuat kode dalam berbagai proyek menggunakan Python (termasuk pengembangan web Django dan pengembangan game Panda3D).

Untuk membantu saya memahami apa yang terjadi, pada dasarnya saya ingin 'melihat' di dalam objek Python untuk melihat bagaimana mereka menandai - seperti metode dan properti mereka.

Jadi katakan saya memiliki objek Python, apa yang saya perlukan untuk mencetak isinya? Apakah itu mungkin?

Jawaban:


352

Python memiliki serangkaian fitur introspeksi yang kuat.

Lihatlah fungsi-fungsi bawaan berikut :

type()dan dir()sangat berguna untuk memeriksa jenis objek dan set atributnya, masing-masing.


25
Tidak tahu istilah itu 'introspeksi'. Itu sangat membantu! Selain semua fungsi yang telah Anda berikan kepada saya ... Terima kasih!
littlejim84

2
properti, metode dan metode statis tidak terkait dengan introspeksi. Semua metode ini menciptakan jenis objek khusus yang dapat digunakan untuk mendefinisikan kelas dengan perilaku khusus, tetapi tidak membantu dalam memeriksa kelas atau konstruksi tersebut.
SingleNegationElimination

Jawaban dari @Brian di bawah ini menunjukkan kepada Anda bagaimana juga melihat kode sumber berbagai objek python dari dalam python. Itulah yang awalnya saya cari dan saya yakin saya tidak akan sendirian. (Mungkin layak termasuk referensi ke jawabannya dalam jawaban ini karena ini yang paling diterima.)
michaelavila

Ini seperti "IntelliSense" bawaan untuk python. Aku menyukainya.
Bruno Bieri

7
saya pikir itu jawaban yang buruk. alih-alih memberi kami solusi, itu hanya memberi kami segala sesuatu yang terkait dengan itu dalam dokumentasi
Ishan Srivastava

176

object.__dict__


12
vars(object)dibuat untuk itu.
liberforce

6
Sebenarnya from pprint import pprint; pprint(vars(object))memberi saya pandangan yang sangat bagus pada isi objek saya. Terima kasih @liberforce
N. Maks

cara terbaik untuk melihat objek dan isinya dalam sebuah string
Peter Krauss

Ini adalah cara yang bagus untuk melihat objek yang menerapkan metode representasi apa pun, atau objek seperti googleapiclient.errors.HttpError yang ketika Anda mencetaknya mereka mencetak informasi yang tidak cukup pasti, terima kasih @ mtasic85
Felipe Valdes

65

Pertama, baca sumbernya.

Kedua, gunakan dir()fungsinya.


92
Saya akan membalik urutan itu.
bayer

5
Sumber lebih informatif daripada dir () dan kebiasaan yang lebih baik untuk dikembangkan.
S.Lott

14
Saya mohon untuk berbeda. dir () jauh lebih cepat dan dalam 99% kasus, mari Anda cari tahu apa yang Anda butuhkan dalam kombinasi dengan bantuan ().
bayer

7
Saya setuju dengan biasanya tidak berguna. Sering kali, panggilan sederhana ke dir () akan cukup, sehingga Anda tidak perlu repot mencari kode sumber.
Sasha Chedygov

3
Kadang-kadang memeriksa objek saat run time bisa bermanfaat tetapi tidak membaca sumber. Misalnya kelas httplib.py dan metode mereka :).
Denis Barmenkov

61

Saya terkejut belum ada bantuan yang disebutkan!

In [1]: def foo():
   ...:     "foo!"
   ...:

In [2]: help(foo)
Help on function foo in module __main__:

foo()
    foo!

Bantuan memungkinkan Anda membaca dokumen dan mendapatkan gagasan tentang atribut apa yang mungkin dimiliki kelas, yang cukup membantu.


Kemudian Anda menggunakan teknik lain yang disebutkan di sini. Tetapi jika dokumen tersedia, pertimbangkan kanon.
Edward Falk

Saya tidak yakin apakah python memperbarui fungsi ini dalam beberapa tahun terakhir, tetapi "help (object_name)" memberikan gambaran lengkap dalam format yang sangat terstruktur. Itu penjaga. Terima kasih.
Brian Cugelman

27

Jika ini untuk eksplorasi untuk melihat apa yang terjadi, saya akan merekomendasikan melihat IPython . Ini menambahkan berbagai cara pintas untuk mendapatkan dokumentasi objek, properti, dan bahkan kode sumber. Misalnya menambahkan "?" untuk suatu fungsi akan memberikan bantuan untuk objek (secara efektif pintas untuk "help (obj)", sedangkan menggunakan dua? (( func??")) akan menampilkan kode sumber jika tersedia.

Ada juga banyak kenyamanan tambahan, seperti penyelesaian tab, pencetakan hasil yang cantik, riwayat hasil dll. Yang membuatnya sangat berguna untuk pemrograman penjelajahan semacam ini.

Untuk penggunaan lebih program introspeksi, builtin dasar seperti dir(), vars(), getattrdll akan berguna, tetapi juga bernilai waktu Anda untuk memeriksa memeriksa modul. Untuk mengambil sumber suatu fungsi, gunakan " inspect.getsource" mis., Terapkan pada dirinya sendiri:

>>> print inspect.getsource(inspect.getsource)
def getsource(object):
    """Return the text of the source code for an object.

    The argument may be a module, class, method, function, traceback, frame,
    or code object.  The source code is returned as a single string.  An
    IOError is raised if the source code cannot be retrieved."""
    lines, lnum = getsourcelines(object)
    return string.join(lines, '')

inspect.getargspec juga sering berguna jika Anda berurusan dengan fungsi pembungkus atau manipulasi, karena akan memberikan nama dan nilai default dari parameter fungsi.


18

Jika Anda tertarik pada GUI untuk ini, lihatlah objbrowser . Ia menggunakan modul inspect dari library standar Python untuk introspeksi objek di bawahnya.

objbrowserscreenshot


9

Anda bisa daftar atribut objek dengan dir () di shell:

>>> dir(object())
['__class__', '__delattr__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__']

Tentu saja, ada juga modul pemeriksa: http://docs.python.org/library/inspect.html#module-inspect


8
"""Visit http://diveintopython.net/"""

__author__ = "Mark Pilgrim (mark@diveintopython.org)"


def info(object, spacing=10, collapse=1):
    """Print methods and doc strings.

    Takes module, class, list, dictionary, or string."""
    methodList = [e for e in dir(object) if callable(getattr(object, e))]
    processFunc = collapse and (lambda s: " ".join(s.split())) or (lambda s: s)
    print "\n".join(["%s %s" %
                     (method.ljust(spacing),
                      processFunc(str(getattr(object, method).__doc__)))
                     for method in methodList])

if __name__ == "__main__":
    print help.__doc__

4
Ini berfungsi dengan baik di python 3 jika Anda hanya menambahkan parens di sekitar cetakan.
ConstantineK

8

Coba ppretty

from ppretty import ppretty


class A(object):
    s = 5

    def __init__(self):
        self._p = 8

    @property
    def foo(self):
        return range(10)


print ppretty(A(), indent='    ', depth=2, width=30, seq_length=6,
              show_protected=True, show_private=False, show_static=True,
              show_properties=True, show_address=True)

Keluaran:

__main__.A at 0x1debd68L (
    _p = 8, 
    foo = [0, 1, 2, ..., 7, 8, 9], 
    s = 5
)

7

Orang lain telah menyebutkan dir () built-in yang terdengar seperti apa yang Anda cari, tapi inilah tip lain yang bagus. Banyak perpustakaan - termasuk sebagian besar perpustakaan standar - didistribusikan dalam bentuk sumber. Berarti Anda dapat dengan mudah membaca kode sumber secara langsung. Kuncinya adalah menemukannya; sebagai contoh:

>>> import string
>>> string.__file__
'/usr/lib/python2.5/string.pyc'

File * .pyc dikompilasi, jadi hapus trailing 'c' dan buka file * .py yang belum dikompilasi di editor atau penampil file favorit Anda:

/usr/lib/python2.5/string.py

Saya menemukan ini sangat berguna untuk menemukan hal-hal seperti pengecualian yang dimunculkan dari API yang diberikan. Detail seperti ini jarang didokumentasikan dengan baik di dunia Python.


7

Meskipun pprinttelah disebutkan oleh orang lain, saya ingin menambahkan beberapa konteks.

Modul pprint menyediakan kemampuan untuk "mencetak cukup" struktur data Python sewenang-wenang dalam bentuk yang dapat digunakan sebagai input ke penerjemah. Jika struktur yang diformat termasuk objek yang bukan tipe Python mendasar, representasi mungkin tidak dapat dimuat. Ini mungkin terjadi jika objek seperti file, soket, kelas, atau instance disertakan, serta banyak objek built-in lainnya yang tidak dapat direpresentasikan sebagai konstanta Python.

pprint mungkin diminati oleh pengembang dengan latar belakang PHP yang mencari alternatif var_dump() .

Objek dengan atribut dict dapat dibuang dengan baik menggunakan pprint()mixed with vars(), yang mengembalikan __dict__atribut untuk modul, kelas, instance, dll .:

from pprint import pprint
pprint(vars(your_object))

Jadi, tidak perlu loop .

Untuk membuang semua variabel yang ada dalam lingkup global atau lokal cukup gunakan:

pprint(globals())
pprint(locals())

locals()menunjukkan variabel yang didefinisikan dalam suatu fungsi.
Ini juga berguna untuk mengakses fungsi dengan nama terkait sebagai kunci string, di antara penggunaan lainnya :

locals()['foo']() # foo()
globals()['foo']() # foo()

Demikian pula, menggunakan dir()untuk melihat isi modul, atau atribut suatu objek.

Dan masih ada lagi.


4

Jika Anda ingin melihat parameter dan metode, seperti yang ditunjukkan orang lain, Anda dapat menggunakan pprintataudir()

Jika Anda ingin melihat nilai sebenarnya dari konten, Anda bisa melakukannya

object.__dict__


4

Dua alat hebat untuk memeriksa kode adalah:

  1. IPython . Terminal python yang memungkinkan Anda untuk memeriksa menggunakan penyelesaian tab.

  2. Gerhana dengan plugin PyDev . Ini memiliki debugger yang sangat baik yang memungkinkan Anda untuk istirahat di tempat tertentu dan memeriksa objek dengan menelusuri semua variabel sebagai pohon. Anda bahkan dapat menggunakan terminal tertanam untuk mencoba kode di tempat itu atau mengetik objek dan tekan '.' untuk memilikinya berikan petunjuk kode untuk Anda.

masukkan deskripsi gambar di sini


3

cetak dan dir bersama-sama bekerja dengan baik


3

Ada pustaka kode python yang dibuat hanya untuk tujuan ini: periksa Diperkenalkan dengan Python 2.7


3

Jika Anda tertarik untuk melihat kode sumber fungsi yang sesuai dengan objek myobj, Anda dapat mengetik iPythonatau Jupyter Notebook:

myobj??


2
import pprint

pprint.pprint(obj.__dict__)

atau

pprint.pprint(vars(obj))

Sementara kode ini dapat menjawab pertanyaan, memberikan konteks tambahan tentang bagaimana dan / atau mengapa memecahkan masalah akan meningkatkan nilai jangka panjang jawaban.
Alexander

1

Jika Anda ingin melihat ke dalam objek hidup, maka inspectmodul python adalah jawaban yang bagus. Secara umum, ini berfungsi untuk mendapatkan kode sumber fungsi yang didefinisikan dalam file sumber di suatu tempat di disk. Jika Anda ingin mendapatkan sumber fungsi langsung dan lambda yang didefinisikan dalam juru bahasa, Anda dapat menggunakan dill.source.getsourcedari dill. Ia juga bisa mendapatkan kode dari metode dan fungsi kelas yang diikat atau tidak terikat yang didefinisikan dalam kari ... namun, Anda mungkin tidak dapat mengkompilasi kode itu tanpa kode objek yang dilampirkan.

>>> from dill.source import getsource
>>> 
>>> def add(x,y):
...   return x+y
... 
>>> squared = lambda x:x**2
>>> 
>>> print getsource(add)
def add(x,y):
  return x+y

>>> print getsource(squared)
squared = lambda x:x**2

>>> 
>>> class Foo(object):
...   def bar(self, x):
...     return x*x+x
... 
>>> f = Foo()
>>> 
>>> print getsource(f.bar)
def bar(self, x):
    return x*x+x

>>> 


0

Selain itu jika Anda ingin melihat ke dalam daftar dan kamus, Anda dapat menggunakan pprint ()


0

Sudah banyak tip bagus, tetapi yang terpendek dan termudah (belum tentu yang terbaik) belum disebutkan:

object?

-3

Coba gunakan:

print(object.stringify())
  • di mana objectnama variabel dari objek yang Anda coba periksa.

Ini mencetak output yang diformat dengan baik dan tab yang menunjukkan semua hierarki kunci dan nilai-nilai dalam objek.

CATATAN: Ini berfungsi di python3. Tidak yakin apakah itu berfungsi di versi sebelumnya

PEMBARUAN: Ini tidak berfungsi pada semua jenis objek. Jika Anda menemukan salah satu dari tipe tersebut (seperti objek Permintaan), gunakan salah satu dari berikut ini sebagai gantinya:

  • dir(object())

atau

import pprint kemudian: pprint.pprint(object.__dict__)


1
Tidak berfungsi pada objek 'Permintaan' "'Permintaan' objek tidak memiliki atribut 'stringify'"
AlxVallejo
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.