Bir Python nesnesinin içine nasıl bakarım?


292

Python kullanarak çeşitli projelerde kod yazmaya başlıyorum (Django web geliştirme ve Panda3D oyun geliştirme dahil).

Neler olup bittiğini anlamama yardımcı olmak için, temel olarak Python nesnelerinin içine nasıl baktıklarını görmek istiyorum - nasıl kullandıklarını görmek için - yöntemleri ve özellikleri gibi.

Diyelim ki bir Python nesnem var, içeriğini yazdırmak için neye ihtiyacım var? Bu mümkün mü?

Yanıtlar:


352

Python güçlü bir içgörü özellikleri kümesine sahiptir.

Aşağıdaki yerleşik işlevlere bir göz atın :

type()ve dir()bir nesnenin türünü ve öznitelik kümesini incelemek için özellikle yararlıdır.


25
Terimin 'iç gözlem' olduğunu bilmiyordum. Bu harika bir yardım! Bana verdiğin tüm fonksiyonlar gibi ... Teşekkürler!
littlejim84

2
özellik, sınıf yöntemi ve statik yöntem içgözlem ile ilgili değildir. Bu yöntemlerin tümü, özel davranışa sahip sınıfları tanımlamak için kullanılabilen, ancak bu sınıfları veya yapıları denetlemede yardımcı olmayan özel nesne türleri oluşturur.
SingleNegationElimination

Aşağıdaki @Brian'ın cevabı, python içinden çeşitli python nesnelerinin kaynak kodunun nasıl görüntüleneceğini gösterir. Aslında aradığım şey buydu ve eminim yalnız olmayacağım. (En çok kabul edildiği için bu cevaba cevabına bir referans eklemeye değer olabilir.)
michaelavila

Python için yerleşik "IntelliSense" gibi . Onu seviyorum.
Bruno Bieri

7
bence bu kötü bir cevap. bize bir çözüm vermek yerine, sadece belgelerde bununla ilgili her şeyi veriyor
Ishan Srivastava

177

object.__dict__


13
vars(object)bunun için yapılır.
liberforce

6
Aslında from pprint import pprint; pprint(vars(object))bana nesnemin içeriği hakkında gerçekten güzel bir görüş verdi. Teşekkürler @liberforce
N.

bir dizede nesne ve içeriğini görmenin en iyi yolu
Peter Krauss

Bu herhangi bir beyan yöntemlerini uygulamak nesneleri görmek için harika bir yoldur veya bunları yazdırırken onlar kesin yetersiz bilgi yazdırmak googleapiclient.errors.HttpError gibi nesneleri, teşekkür @ mtasic85
Felipe Valdes

65

İlk olarak, kaynağı okuyun.

İkinci olarak, dir()fonksiyonu kullanın .


92
Bu düzeni tersine çevirirdim.
bayer

5
Kaynak dir () 'den daha bilgilendiricidir ve geliştirilmesi daha iyi bir alışkanlıktır.
S.Lott

14
Naçizane size katılmıyorum. dir () çok daha hızlıdır ve vakaların% 99'unda yardım () ile birlikte neye ihtiyacınız olduğunu öğrenelim.
bayer

7
Genelde katılıyorum. Çoğu zaman, basit bir dir () çağrısı yeterli olur, böylece kaynak koduna bakmak zorunda kalmazsınız.
Sasha Chedygov

3
Nesneleri çalışma zamanında incelemek yararlı olabilir, ancak kaynakları okumak yararlı olmayabilir. Örneğin httplib.py sınıfları ve yöntemleri :).
Denis Barmenkov

61

Henüz kimsenin bahsetmediğine şaşırdım!

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

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

foo()
    foo!

Yardım, öğretiyi okumanızı ve bir sınıfın sahip olabileceği özellikler hakkında bir fikir edinmenizi sağlar, bu da oldukça yararlıdır.


O zaman burada bahsedilen diğer teknikleri kullanıyorsunuz. Ama eğer öğreti varsa, bunu düşünün.
Edward Falk

Python'un son birkaç yıldır bu işlevi güncellediğinden emin değilim, ancak "help (object_name)" son derece yapılandırılmış bir formatta tam bir genel bakış sunuyor. Bu bir kaleci. Teşekkürler.
Brian Cugelman

27

Neler olup bittiğini görmek için keşif içinse, IPython'a bakmanızı tavsiye ederim . Bu, bir nesnenin belgelerini, özelliklerini ve hatta kaynak kodunu elde etmek için çeşitli kısayollar ekler. Örneğin, "?" bir işleve nesne için yardım verecektir (etkin bir "yardım (obj)" kısayolu, iki? 's (" func??" kullanarak wheras varsa kaynak kodunu görüntüler.

Sekme tamamlama, sonuçların güzel yazdırılması, sonuç geçmişi vb. Gibi bu tür keşif programlama için çok kullanışlı hale getiren birçok ek kolaylık da vardır.

İçgözlem daha programlı kullanım için, temel yerleşikleri gibi dir(), vars(), getattrfaydalı olacaktır vs, ancak kontrol etmek için zaman harcamaya değer incelemek modülü. Bir işlevin kaynağını getirmek için, " inspect.getsource" kullanın , örneğin, kendisine uygulama:

>>> 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 işlev parametrelerinin adlarını ve varsayılan değerlerini vereceğinden, işlevleri kaydırma veya değiştirme ile uğraşıyorsanız da yararlıdır.


19

Bunun için bir GUI ile ilgileniyorsanız, objbrowser'a bir göz atın . Altındaki nesne introspeksiyonu için Python standart kütüphanesindeki inspect modülünü kullanır.

objbrowserscreenshot


9

Kabukta dir () bulunan bir nesnenin niteliklerini listeleyebilirsiniz:

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

Elbette, inceleme modülü de var: 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
Baskıların etrafına sadece parens eklerseniz bu, python 3'te iyi çalışır.
ConstantineK

8

Ppretty'i deneyin

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)

Çıktı:

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

8

pprintBaşkaları tarafından zaten bahsedilmiş olsa da , bir bağlam eklemek istiyorum.

Pprint modülü, keyfi Python veri yapılarını yorumlayıcıya girdi olarak kullanılabilecek bir biçimde "güzel yazdırma" olanağı sağlar. Biçimlendirilmiş yapılar temel Python türü olmayan nesneler içeriyorsa, gösterim yüklenemeyebilir. Dosyalar, soketler, sınıflar veya örnekler gibi nesnelerin yanı sıra Python sabitleri olarak temsil edilemeyen diğer birçok yerleşik nesnenin de dahil edilmesi durumunda bu durum söz konusu olabilir.

pprintbir alternatif arayan bir PHP geçmişi olan geliştiriciler tarafından yüksek talep görüyor olabilir var_dump().

Bir dict özniteliğine sahip nesneler, bir modül, sınıf, örnek vb . İçin öznitelik döndüren pprint()karışık ile güzelce dökülebilir.vars()__dict__

from pprint import pprint
pprint(vars(your_object))

Yani, bir döngüye gerek yok .

Bulunan tüm değişkenleri dökümü için küresel veya yerel kapsam sadece kullanım:

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

locals()bir işlevde tanımlanan değişkenleri gösterir. Diğer kullanımların
yanı sıra, ilgili ada sahip işlevlere dize anahtarı olarak erişmek de yararlıdır :

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

Benzer şekilde, dir()bir modülün içeriğini veya bir nesnenin niteliklerini görmek için kullanılır .

Ve daha fazlası var.


7

Diğerleri zaten aradığınıza benzeyen dir () yerleşikten bahsetmişlerdir, ancak burada başka bir iyi ipucu. Standart kütüphanelerin çoğu da dahil olmak üzere birçok kütüphane kaynak biçiminde dağıtılır. Yani doğrudan kaynak kodunu kolayca okuyabilirsiniz. İşin püf noktası onu bulmakta; Örneğin:

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

* .Pyc dosyası derlenmiştir, bu nedenle sondaki 'c' işaretini kaldırın ve derlenmemiş * .py dosyasını favori düzenleyiciniz veya dosya görüntüleyicinizde açın:

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

Bunu, belirli bir API'dan istisnalar gibi şeyler keşfetmek için inanılmaz derecede faydalı buldum. Bu tür detaylar Python dünyasında nadiren iyi belgelenmiştir.


4

Parametrelere ve yöntemlere bakmak isterseniz, diğerleri işaret ettiği gibi, iyi kullanabilirsiniz pprintveyadir()

İçeriğin gerçek değerini görmek istiyorsanız,

object.__dict__


4

Kodu incelemek için iki harika araç:

  1. IPython . Sekme tamamlamayı kullanarak incelemenizi sağlayan bir python terminali.

  2. Eclipse ile Pydev eklentisi . Belirli bir noktada kırmanıza ve tüm değişkenleri bir ağaç olarak tarayarak nesneleri incelemenize izin veren mükemmel bir hata ayıklayıcıya sahiptir. Hatta o noktada kodu denemek veya nesneyi yazmak için 'gömülü' terminali kullanabilirsiniz. sizin için kod ipuçları vermesini sağlamak.

resim açıklamasını buraya girin




3

Eğer nesneye karşılık gelen fonksiyonun kaynak kodunu görmek için ilgilenen varsa myobj, sen yazabilirsiniz iPythonya Jupyter Notebook:

myobj??


2
import pprint

pprint.pprint(obj.__dict__)

veya

pprint.pprint(vars(obj))

Bu kod soruyu cevaplayabilirken, sorunun nasıl ve / veya neden çözüldüğüne dair ek bağlam sağlamak yanıtlayıcının uzun vadeli değerini artıracaktır.
Alexander

1

Canlı bir nesnenin içine bakmak istiyorsanız, python'un inspectmodülü iyi bir cevaptır. Genel olarak, diskte bir yerde bir kaynak dosyada tanımlanan işlevlerin kaynak kodunu almak için çalışır. Yorumlayıcıda tanımlandı canlı fonksiyonlar ve lambdas kaynağını elde etmek istiyorsanız, kullanabileceğiniz dill.source.getsourcedan dill. Ayrıca, kodları curries'de tanımlanan bağlı veya bağlı olmayan sınıf yöntemlerinden ve işlevlerinden de alabilir ... ancak, bu kodu çevreleyen nesnenin kodu olmadan derleyemeyebilirsiniz.

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

>>> 


1

Zaten birçok iyi ipucu, ancak en kısa ve en kolay (mutlaka en iyisi değil) henüz belirtilmemiş:

object?

0

Ayrıca listenin ve sözlüklerin içine bakmak isterseniz pprint () kullanabilirsiniz.


-4

Kullanmayı deneyin:

print(object.stringify())
  • objectincelemeye çalıştığınız nesnenin değişken adı nerede .

Bu, nesnedeki tüm anahtar ve değer hiyerarşisini gösteren güzel biçimlendirilmiş ve sekmeli bir çıktı yazdırır.

Not: Bu python3 çalışır. Önceki sürümlerde çalışıp çalışmadığından emin değilim

GÜNCELLEME: Bu, tüm nesne türlerinde çalışmaz. Bu türlerden biriyle (bir Request nesnesi gibi) karşılaşırsanız, bunun yerine aşağıdakilerden birini kullanın:

  • dir(object())

veya

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


1
'İstek' nesnesinde çalışmaz '' İstek 'nesnesinin' stringify 'özelliği yoktur
AlxVallejo
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.