ฉันจะดูภายในวัตถุ Python ได้อย่างไร


292

ฉันเริ่มเขียนโค้ดในโครงการต่าง ๆ โดยใช้ Python (รวมถึงการพัฒนาเว็บไซต์ Django และการพัฒนาเกม Panda3D)

เพื่อช่วยให้ฉันเข้าใจสิ่งที่เกิดขึ้นฉันต้องการ 'ดู' ภายในวัตถุ Python โดยทั่วไปเพื่อดูว่าพวกเขาทำเครื่องหมายเช่นวิธีการและคุณสมบัติของพวกเขา

ดังนั้นถ้าฉันมีวัตถุ Python ฉันต้องพิมพ์เนื้อหาอะไร เป็นไปได้ไหม

คำตอบ:


352

Python มีชุดคุณสมบัติวิปัสสนาที่รัดกุม

ดูฟังก์ชั่นในตัวต่อไปนี้:

type()และdir()มีประโยชน์อย่างยิ่งสำหรับการตรวจสอบประเภทของวัตถุและชุดคุณลักษณะตามลำดับ


25
ไม่ทราบคำว่า 'วิปัสสนา' นั่นเป็นความช่วยเหลือที่ยอดเยี่ยม! เช่นเดียวกับฟังก์ชั่นทั้งหมดที่คุณให้ฉัน ... ขอบคุณ!
littlejim84

2
คุณสมบัติ classmethod และ staticmethod ไม่เกี่ยวข้องกับวิปัสสนา วิธีการเหล่านี้ทั้งหมดสร้างวัตถุชนิดพิเศษที่สามารถใช้เพื่อกำหนดคลาสที่มีพฤติกรรมพิเศษ แต่ไม่มีความช่วยเหลือในการตรวจสอบคลาสหรือโครงสร้างเหล่านั้น
SingleNegationElimination

คำตอบจาก @Brian ด้านล่างแสดงวิธีดูซอร์สโค้ดของออบเจกต์หลามต่างๆจากภายในหลาม นั่นคือสิ่งที่ฉันค้นหาในตอนแรกและฉันแน่ใจว่าฉันจะไม่อยู่คนเดียว (มันอาจจะคุ้มค่ารวมถึงการอ้างอิงถึงคำตอบของเขาในคำตอบนี้เพราะมันได้รับการยอมรับมากที่สุด)
michaelavila

มันเหมือน"IntelliSense" ในตัวสำหรับไพ ธ อน ฉันรักมัน.
Bruno Bieri

7
ฉันคิดว่ามันเป็นคำตอบที่ไม่ดี แทนที่จะให้วิธีการแก้ปัญหาแก่เราเพียงแค่ให้ทุกสิ่งที่เกี่ยวข้องกับสิ่งนั้นในเอกสารประกอบ
Ishan Srivastava

177

object.__dict__


13
vars(object)ทำเพื่อสิ่งนั้น
ปลดเปลื้อง

6
ที่จริงแล้วfrom pprint import pprint; pprint(vars(object))ฉันให้มุมมองที่ดีมากกับเนื้อหาของวัตถุ ขอบคุณ @liberforce
N. Maks

วิธีที่ดีที่สุดในการดูวัตถุและเนื้อหาในสตริง
Peter Krauss

นี่เป็นวิธีที่ดีในการดูวัตถุที่ใช้วิธีการแสดงหรือวัตถุเช่น googleapiclient.errors.HttpError ซึ่งเมื่อคุณพิมพ์พวกเขาพวกเขาพิมพ์ข้อมูลไม่เพียงพอแน่นอน @ mtasic85
Felipe Valdes

65

ก่อนอื่นให้อ่านซอร์ส

ประการที่สองใช้dir()ฟังก์ชั่น


92
ฉันจะกลับคำสั่งที่
bayer

5
แหล่งข้อมูลนั้นมีข้อมูลมากกว่า dir () และเป็นนิสัยที่ดีกว่าในการพัฒนา
S.Lott

14
ฉันขอแตกต่าง dir () เร็วขึ้นมากและในกรณี 99% ให้คุณค้นหาสิ่งที่คุณต้องการร่วมกับความช่วยเหลือ ()
bayer

7
ฉันเห็นด้วยกับมักจะไร้ค่า บ่อยครั้งที่การเรียกไปที่ dir () อย่างง่ายจะช่วยให้คุณประหยัดเวลาในการมองผ่านซอร์สโค้ด
Sasha Chedygov

3
บางครั้งการตรวจสอบวัตถุ ณ รันไทม์อาจมีประโยชน์ แต่ไม่สามารถอ่านแหล่งข้อมูลได้ เช่นคลาส httplib.py และวิธีการของพวกเขา :)
เดนิส Barmenkov

61

ฉันประหลาดใจที่ไม่มีใครพูดถึงความช่วยเหลือเลย!

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

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

foo()
    foo!

ช่วยให้คุณอ่าน docstring และรับทราบว่าคุณลักษณะที่คลาสใดอาจมีซึ่งเป็นประโยชน์มาก


จากนั้นคุณใช้เทคนิคอื่น ๆ ที่กล่าวถึงที่นี่ แต่ถ้า docstring พร้อมใช้งานให้พิจารณาเป็น canon
Edward Falk

ฉันไม่แน่ใจว่าหลามปรับปรุงฟังก์ชันนี้ในไม่กี่ปีที่ผ่านมา แต่ "help (object_name)" ให้ภาพรวมแบบเต็มในรูปแบบที่มีโครงสร้างสูง มันเป็นผู้รักษาประตู ขอบคุณ
Brian Cugelman

27

ถ้านี่เป็นสำหรับการสำรวจเพื่อดูสิ่งที่เกิดขึ้นผมขอแนะนำให้มองหาที่IPython เพิ่มทางลัดต่าง ๆ เพื่อรับเอกสารประกอบวัตถุคุณสมบัติและแม้แต่ซอร์สโค้ด ตัวอย่างเช่นการผนวก "?" ฟังก์ชั่นจะให้ความช่วยเหลือสำหรับวัตถุ (ทางลัดที่มีประสิทธิภาพสำหรับ "ความช่วยเหลือ (obj)" ในกรณีที่ใช้สอง? (" func??")) จะแสดงซอร์สโค้ดถ้ามันมีอยู่

นอกจากนี้ยังมีสิ่งอำนวยความสะดวกเพิ่มเติมมากมายเช่นการเติมแท็บ, การพิมพ์ผลลัพธ์, ประวัติผลลัพธ์ ฯลฯ ซึ่งทำให้สะดวกมากสำหรับการเขียนโปรแกรมเชิงสำรวจประเภทนี้

สำหรับการใช้งานการเขียนโปรแกรมมากขึ้นของวิปัสสนาที่ builtins พื้นฐานเช่นdir(), vars(), getattrฯลฯ จะเป็นประโยชน์ แต่มันเป็นอย่างดีคุ้มค่าเวลาของคุณเพื่อตรวจสอบตรวจสอบโมดูล ในการดึงที่มาของฟังก์ชั่นให้ใช้ " inspect.getsource" เช่นนำไปใช้กับตัวเอง:

>>> 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 นอกจากนี้ยังมีประโยชน์บ่อยถ้าคุณกำลังจัดการกับการตัดหรือจัดการฟังก์ชั่นเนื่องจากมันจะให้ชื่อและค่าเริ่มต้นของพารามิเตอร์ฟังก์ชั่น


19

หากคุณกำลังสนใจใน GUI สำหรับนี้จะดูที่objbrowser มันใช้โมดูลตรวจสอบจากห้องสมุดมาตรฐาน Python สำหรับการวิปัสสนาวัตถุภายใต้

objbrowserscreenshot


9

คุณสามารถแสดงรายการคุณสมบัติของวัตถุด้วย dir () ในเปลือก:

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

แน่นอนว่ายังมีโมดูลตรวจสอบ: 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
วิธีนี้ใช้งานได้ดีใน python 3 หากคุณเพียงเพิ่ม parens รอบ ๆ งานพิมพ์
ConstantineK

8

ลอง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)

เอาท์พุท:

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

8

ในขณะที่pprintคนอื่น ๆ พูดถึงแล้วฉันต้องการเพิ่มบริบท

โมดูล pprint ให้ความสามารถในการ "สวย - พิมพ์" โครงสร้างข้อมูล Python โดยพลการในรูปแบบที่สามารถใช้เป็นอินพุตไปยังล่าม หากโครงสร้างที่จัดรูปแบบมีวัตถุที่ไม่ใช่ประเภท Python พื้นฐานการแสดงอาจไม่สามารถโหลดได้ นี่อาจเป็นกรณีที่วัตถุเช่นไฟล์ซ็อกเก็ตคลาสหรืออินสแตนซ์รวมอยู่รวมทั้งวัตถุอื่น ๆ ในตัวที่ไม่สามารถใช้แทนค่าคงที่ของ Python ได้

pprintอาจจะอยู่ในความต้องการสูงโดยนักพัฒนาที่มีพื้นหลัง PHP var_dump()ที่กำลังมองหาทางเลือกในการ

วัตถุที่มีแอตทริบิวต์ dict สามารถทิ้งไว้อย่างดีโดยใช้การpprint()ผสมกับvars()ซึ่งจะส่งคืน__dict__แอตทริบิวต์สำหรับโมดูลคลาสคลาสอินสแตนซ์และอื่น ๆ :

from pprint import pprint
pprint(vars(your_object))

ดังนั้นจำเป็นที่จะต้องห่วงไม่มี

หากต้องการดัมพ์ตัวแปรทั้งหมดที่มีอยู่ในขอบเขตโกลบอลหรือโลคัลให้ใช้:

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

locals()แสดงตัวแปรที่กำหนดในฟังก์ชั่น
นอกจากนี้ยังมีประโยชน์ในการเข้าถึงฟังก์ชั่นที่มีชื่อที่เกี่ยวข้องเป็นคีย์สตริงรวมถึงการใช้งานอื่น ๆ :

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

ในทำนองเดียวกันการใช้dir()เพื่อดูเนื้อหาของโมดูลหรือคุณลักษณะของวัตถุ

และยังมีอีกมาก


7

คนอื่นพูดถึง dir () ในตัวซึ่งฟังดูเหมือนสิ่งที่คุณกำลังมองหา แต่นี่เป็นคำแนะนำที่ดีอีกข้อหนึ่ง ห้องสมุดจำนวนมาก - รวมถึงห้องสมุดมาตรฐานส่วนใหญ่ - กระจายอยู่ในรูปแบบของแหล่งที่มา หมายความว่าคุณสามารถอ่านซอร์สโค้ดได้ง่าย เคล็ดลับอยู่ในการค้นหา ตัวอย่างเช่น:

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

ไฟล์ * .pyc ถูกคอมไพล์ดังนั้นให้ลบส่วนท้าย 'c' และเปิดไฟล์ * .py ที่ยังไม่ได้คอมไพล์ในตัวแก้ไขหรือโปรแกรมดูไฟล์ที่คุณชื่นชอบ:

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

ฉันพบว่าสิ่งนี้มีประโยชน์อย่างมากในการค้นพบสิ่งต่าง ๆ เช่นข้อยกเว้นที่ยกมาจาก API ที่กำหนด รายละเอียดชนิดนี้ไม่ค่อยได้รับการบันทึกไว้อย่างดีในโลก Python


4

หากคุณต้องการดูพารามิเตอร์และวิธีการตามที่คนอื่น ๆ ได้ชี้ให้เห็นคุณอาจใช้pprintหรือdir()

หากคุณต้องการดูมูลค่าที่แท้จริงของเนื้อหาคุณสามารถทำได้

object.__dict__


4

เครื่องมือที่ยอดเยี่ยมสำหรับการตรวจสอบโค้ดคือ:

  1. IPython หลาม terminal ที่ช่วยให้คุณสามารถตรวจสอบการใช้แท็บเสร็จ

  2. คราสกับปลั๊กอิน PyDev มันมีดีบักเกอร์ที่ยอดเยี่ยมที่ช่วยให้คุณสามารถทำลายที่จุดที่กำหนดและตรวจสอบวัตถุโดยการเรียกดูตัวแปรทั้งหมดเป็นต้นไม้ คุณสามารถใช้เทอร์มินัลฝังตัวเพื่อลองโค้ดที่จุดนั้นหรือพิมพ์วัตถุแล้วกด '.' ที่จะมีมันให้คำแนะนำรหัสสำหรับคุณ

ป้อนคำอธิบายรูปภาพที่นี่




3

หากคุณสนใจที่จะเห็นซอร์สโค้ดของฟังก์ชันที่สอดคล้องกับวัตถุmyobjคุณสามารถพิมพ์iPythonหรือJupyter Notebook:

myobj??


2
import pprint

pprint.pprint(obj.__dict__)

หรือ

pprint.pprint(vars(obj))

ในขณะที่รหัสนี้อาจตอบคำถามให้บริบทเพิ่มเติมเกี่ยวกับวิธีการและ / หรือทำไมมันแก้ปัญหาจะปรับปรุงค่าระยะยาวของคำตอบ
Alexander

1

หากคุณต้องการดูภายในวัตถุสดแล้วinspectโมดูลของงูใหญ่เป็นคำตอบที่ดี โดยทั่วไปแล้วจะใช้เพื่อรับซอร์สโค้ดของฟังก์ชั่นที่กำหนดไว้ในไฟล์ต้นฉบับบางแห่งบนดิสก์ หากคุณต้องการที่จะได้รับแหล่งที่มาของฟังก์ชั่นที่อยู่อาศัยและ lambdas ที่ถูกกำหนดไว้ในล่ามที่คุณสามารถใช้จากdill.source.getsource dillนอกจากนี้ยังสามารถรับรหัสสำหรับจากวิธีการเรียนที่ถูกผูกไว้หรือไม่ถูกผูกไว้และในฟังก์ชัน curries ... อย่างไรก็ตามคุณอาจไม่สามารถรวบรวมรหัสนั้นได้โดยไม่ต้องใช้รหัสของวัตถุที่ล้อมรอบ

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

เคล็ดลับที่ดีหลายอย่างแล้ว แต่สั้นที่สุดและง่ายที่สุด (ไม่จำเป็นต้องดีที่สุด) ยังไม่ได้กล่าวถึง:

object?

0

นอกจากนี้หากคุณต้องการดูภายในรายการและพจนานุกรมคุณสามารถใช้ pprint ()


-4

ลองใช้:

print(object.stringify())
  • โดยที่objectเป็นชื่อตัวแปรของวัตถุที่คุณพยายามตรวจสอบ

สิ่งนี้จะพิมพ์เอาต์พุตที่มีการจัดรูปแบบและแท็บที่แสดงลำดับชั้นของคีย์และค่าทั้งหมดในวัตถุ

หมายเหตุ: มันใช้งานได้ใน python3 ไม่แน่ใจว่าใช้ได้กับเวอร์ชั่นก่อนหน้าหรือไม่

UPDATE: สิ่งนี้ไม่สามารถใช้ได้กับวัตถุทุกประเภท หากคุณพบหนึ่งในประเภทเหล่านั้น (เช่นวัตถุคำขอ) ให้ใช้วิธีใดวิธีหนึ่งต่อไปนี้แทน:

  • dir(object())

หรือ

import pprint แล้ว: pprint.pprint(object.__dict__)


1
ไม่ทำงานบนวัตถุ 'คำขอ' "วัตถุคำขอ" ไม่มีแอตทริบิวต์ "stringify" "
AlxVallejo
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.