มีฟังก์ชันในตัวเพื่อพิมพ์คุณสมบัติและค่าปัจจุบันของวัตถุทั้งหมดหรือไม่?


957

ดังนั้นสิ่งที่ฉันกำลังมองหาที่นี่คือสิ่งที่ต้องการฟังก์ชั่นprint_rของ PHP

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

คำตอบ:


590

คุณกำลังผสมสองสิ่งที่แตกต่างกันจริงๆ

การใช้งานdir(), vars()หรือinspectโมดูลที่จะได้รับสิ่งที่คุณมีความสนใจใน (ผมใช้__builtins__เป็นตัวอย่างคุณสามารถใช้วัตถุใด ๆ แทน)

>>> l = dir(__builtins__)
>>> d = __builtins__.__dict__

พิมพ์พจนานุกรมดังกล่าวตามที่คุณต้องการ:

>>> print l
['ArithmeticError', 'AssertionError', 'AttributeError',...

หรือ

>>> from pprint import pprint
>>> pprint(l)
['ArithmeticError',
 'AssertionError',
 'AttributeError',
 'BaseException',
 'DeprecationWarning',
...

>>> pprint(d, indent=2)
{ 'ArithmeticError': <type 'exceptions.ArithmeticError'>,
  'AssertionError': <type 'exceptions.AssertionError'>,
  'AttributeError': <type 'exceptions.AttributeError'>,
...
  '_': [ 'ArithmeticError',
         'AssertionError',
         'AttributeError',
         'BaseException',
         'DeprecationWarning',
...

การพิมพ์แบบสวยก็มีอยู่ในดีบักเกอร์แบบโต้ตอบด้วยคำสั่ง:

(Pdb) pp vars()
{'__builtins__': {'ArithmeticError': <type 'exceptions.ArithmeticError'>,
                  'AssertionError': <type 'exceptions.AssertionError'>,
                  'AttributeError': <type 'exceptions.AttributeError'>,
                  'BaseException': <type 'exceptions.BaseException'>,
                  'BufferError': <type 'exceptions.BufferError'>,
                  ...
                  'zip': <built-in function zip>},
 '__file__': 'pass.py',
 '__name__': '__main__'}

28
น่าแปลกที่ดูเหมือนว่าวัตถุทั้งหมดไม่ได้มี__dict__สมาชิก ( re.MatchObjectตัวอย่างเช่น) แต่ builtin dir()ใช้ได้กับวัตถุทั้งหมด
เตาแก๊ส

print re.compile(r'slots').search('No slots here either.').__slots__
เตาแก๊ส

3
ใหม่ให้ฉัน ขอบคุณ. จุดดังกล่าวทำให้โปรแกรมแยกวิเคราะห์เส้นทางโมดูลสมองของฉัน ไม่เคยพิจารณาแม้แต่ "โมดูล" ภาษาละติน
เตาอบ

4
ทำไมคุณไม่พูดถึงinspectโมดูลเพิ่มเติมในคำตอบของคุณ? ฉันคิดว่ามันเป็นสิ่งที่ใกล้เคียงกับ print_r หรือ var_dump
Hai Phaikawl

1
คุณจะเข้าถึงค่าที่อยู่เบื้องหลังแอตทริบิวต์ที่ระบุไว้ได้dir()อย่างไร? dir()ส่งกลับรายการชื่อเท่านั้นไม่ใช่ทั้งหมดที่มีอยู่ในvars()หรือใน__dict__แอตทริบิวต์
HelloGoodbye

981

คุณต้องการvars()ผสมกับpprint():

from pprint import pprint
pprint(vars(your_object))

24
vars()เพียงแค่คืนค่า__dict__อาร์กิวเมนต์ของมันและนั่นก็เป็นทางเลือกdir()ในกรณีที่ไม่มี__dir__วิธีการ ดังนั้นใช้dir()ในตอนแรกตามที่ฉันพูด

28
@hop: dir()ช่วยให้คุณทั้งหมดที่สร้างขึ้นในสิ่งที่คุณอาจไม่สนใจเกี่ยวกับชอบและ__str__ ไม่ __new__var()
Timmmm

14
สิ่งนี้ล้มเหลวในชุดและวัตถุอื่น ๆ ที่ไม่มี__dict__แอตทริบิวต์
Anatoly techtonik

209
def dump(obj):
  for attr in dir(obj):
    print("obj.%s = %r" % (attr, getattr(obj, attr)))

มีฟังก์ชั่นของบุคคลที่สามมากมายที่เพิ่มสิ่งต่าง ๆ เช่นการจัดการข้อผิดพลาดการพิมพ์ตัวละครในระดับชาติ / พิเศษการเรียกใช้ซ้ำไปยังวัตถุที่ซ้อนกันเป็นต้นตามการตั้งค่าของผู้เขียน แต่โดยทั่วไปแล้วพวกเขาก็เดือดปุด ๆ


5
unpythonic เพราะทำตามไม่ได้คิดค้น - ที่นี่

14
พูดว่าอะไรนะ? แน่นอนว่าคุณสามารถใช้getmembers()ฟังก์ชั่นในinspectโมดูลมาตรฐานได้แต่ฉันคิดว่านี่จะมีประโยชน์มากกว่าเพราะมันแสดงวิธีการวิปัสสนาโดยทั่วไป
Dan Lenski

20
ไม่ใช่เลย. dir (obj) แสดงคุณสมบัติที่ไม่พบใน__dict__(เช่น__doc__และ__module__) นอกจากนี้ไม่ได้ทำงานเลยสำหรับวัตถุประกาศด้วย__dict__ __slots__โดยทั่วไปแล้ว__dict__จะแสดงคุณสมบัติระดับผู้ใช้ที่จัดเก็บจริงในพจนานุกรมภายใน dir () แสดงมากขึ้น
Dan Lenski

8
คลาส / วัตถุบางอย่างไม่มี__dict__แอตทริบิวต์ / สมาชิกใด ๆ ฉันรู้ว่ามันบ้า แต่จริง บิวด์อินชอบintและstrหรือre.MatchObjects เป็นตัวอย่างทั่วไป ลอง'hello'.__dict__แล้วลองdir('hello')
เตาแก๊ส

11
ฉันไม่สนใจหรอกว่านั่นคือ "เสียงไพเราะ" หรืออะไรก็ตาม มันทำให้งานเสร็จซึ่งในการดีบักเป็นสิ่งเดียวที่สำคัญ
hidefromkgb

59

ได้รับการกล่าวถึงdirแต่นั่นจะให้ชื่อของคุณลักษณะเท่านั้น ถ้าคุณต้องการค่าของพวกเขาเช่นกันลอง __ ดิช __

class O:
   def __init__ (self):
      self.value = 3

o = O()

นี่คือผลลัพธ์:

>>> o.__dict__

{'value': 3}

9
วัตถุอย่างที่setไม่ได้มี__dict__ดังนั้นสำหรับพวกเขามันจะล้มเหลวด้วยAttributeError: 'set' object has no attribute '__dict__'
Anatoly techtonik

23

คุณสามารถใช้ฟังก์ชัน "dir ()" เพื่อทำสิ่งนี้

>>> import sys
>>> dir(sys)
['__displayhook__', '__doc__', '__excepthook__', '__name__', '__stderr__', '__stdin__', '__stdo
t__', '_current_frames', '_getframe', 'api_version', 'argv', 'builtin_module_names', 'byteorder
, 'call_tracing', 'callstats', 'copyright', 'displayhook', 'dllhandle', 'exc_clear', 'exc_info'
 'exc_type', 'excepthook', 'exec_prefix', 'executable', 'exit', 'getcheckinterval', 'getdefault
ncoding', 'getfilesystemencoding', 'getrecursionlimit', 'getrefcount', 'getwindowsversion', 'he
version', 'maxint', 'maxunicode', 'meta_path', 'modules', 'path', 'path_hooks', 'path_importer_
ache', 'platform', 'prefix', 'ps1', 'ps2', 'setcheckinterval', 'setprofile', 'setrecursionlimit
, 'settrace', 'stderr', 'stdin', 'stdout', 'subversion', 'version', 'version_info', 'warnoption
', 'winver']
>>>

อีกคุณสมบัติที่มีประโยชน์คือความช่วยเหลือ

>>> help(sys)
Help on built-in module sys:

NAME
    sys

FILE
    (built-in)

MODULE DOCS
    http://www.python.org/doc/current/lib/module-sys.html

DESCRIPTION
    This module provides access to some objects used or maintained by the
    interpreter and to functions that interact strongly with the interpreter.

    Dynamic objects:

    argv -- command line arguments; argv[0] is the script pathname if known

22

หากต้องการพิมพ์สถานะปัจจุบันของวัตถุคุณอาจ:

>>> obj # in an interpreter

หรือ

print repr(obj) # in a script

หรือ

print obj

สำหรับชั้นเรียนของคุณกำหนด__str__หรือ__repr__วิธีการ จากเอกสาร Python :

__repr__(self)เรียกว่าโดยrepr()ฟังก์ชันในตัวและการแปลงสตริง (อัญประกาศย้อนกลับ) เพื่อคำนวณการแสดงสตริง "เป็นทางการ" ของวัตถุ ถ้าเป็นไปได้ทั้งหมดควรมีลักษณะเป็นนิพจน์ Python ที่ถูกต้องซึ่งสามารถใช้เพื่อสร้างวัตถุที่มีค่าเดียวกัน (ให้เป็นสภาพแวดล้อมที่เหมาะสม) หากไม่สามารถทำได้ควรส่งคืนสตริงของฟอร์ม "<... คำอธิบายที่เป็นประโยชน์บางอย่าง ... >" ค่าส่งคืนจะต้องเป็นวัตถุสตริง หากมีการกำหนดระดับrepr () แต่ไม่ได้__str__()แล้ว__repr__()ยังใช้เมื่อมี "ระบบ" การแสดงสตริงอินสแตนซ์ของการเรียนที่จำเป็น โดยทั่วไปจะใช้สำหรับการดีบักดังนั้นสิ่งสำคัญคือการแสดงข้อมูลที่หลากหลายและไม่คลุมเครือ

__str__(self)เรียกว่าโดยstr()ฟังก์ชันในตัวและโดยคำสั่งการพิมพ์เพื่อคำนวณการแสดงสตริง "ไม่เป็นทางการ" ของวัตถุ สิ่งนี้แตกต่างจาก__repr__()ที่ไม่จำเป็นต้องเป็นนิพจน์ Python ที่ถูกต้อง: อาจใช้การแทนแบบที่สะดวกกว่าหรือรัดกุมแทน ค่าส่งคืนจะต้องเป็นวัตถุสตริง


ตัวเลือกนี้มีประโยชน์สำหรับการพิมพ์สตริงที่เชื่อมโยงกับเนื้อหาของวัตถุ:print "DEBUG: object value: " + repr(obj)
AlejandroVD

17

อาจคุ้มค่าที่จะเช็คเอาท์ -

มี Python ที่เทียบเท่ากับ Perl's Data :: Dumper หรือไม่?

คำแนะนำของฉันคือ -

https://gist.github.com/1071857

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

มีหลายสิ่งที่ python pprint มาตรฐานล้มเหลวในการบรรลุโดยเฉพาะอย่างยิ่งมันหยุดลงเมื่อเห็นตัวอย่างของวัตถุและให้ตัวชี้ฐานสิบหกภายในของวัตถุ (errr ตัวชี้นั้นไม่ใช่การใช้งานทั้งหมดโดยมาก ทาง) ดังนั้นโดยสรุปแล้ว Python เป็นเรื่องเกี่ยวกับกระบวนทัศน์เชิงวัตถุที่ยอดเยี่ยมนี้ แต่เครื่องมือที่คุณได้รับจากกล่องออกแบบมาเพื่อทำงานกับสิ่งอื่นนอกเหนือจากวัตถุ

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


นี่ควรจะเป็น pip และ deb ไม่ใช่แค่ส่วนสำคัญ!
phobie

2
> โดยสรุปแล้ว python เป็นเรื่องเกี่ยวกับกระบวนทัศน์เชิงวัตถุที่ยอดเยี่ยมนี้ แต่เครื่องมือที่คุณได้รับมาจากกล่องออกแบบมาเพื่อทำงานกับสิ่งอื่นนอกเหนือจากวัตถุ ... ค่อนข้างอ้างสิทธิ์เมื่อตัวอย่างเดียวที่คุณให้คือ โมดูลที่มีความสำคัญรอง
memeplex

@emeplex มันบอกว่างูเหลือมเป็นเรื่องของ OOP หรือเปล่า?
Peter Wood

ตกลงมันแค่บอกว่ามันคือทั้งหมดที่เกี่ยวกับ OOP ที่ยอดเยี่ยมนี้ไม่ดีของฉัน
memeplex

13

help(your_object)ผมขอแนะนำให้ใช้

help(dir)

 If called without an argument, return the names in the current scope.
 Else, return an alphabetized list of names comprising (some of) the attributes
 of the given object, and of attributes reachable from it.
 If the object supplies a method named __dir__, it will be used; otherwise
 the default dir() logic is used and returns:
 for a module object: the module's attributes.
 for a class object:  its attributes, and recursively the attributes
 of its bases.
 for any other object: its attributes, its class's attributes, and
 recursively the attributes of its class's base classes.

help(vars)

Without arguments, equivalent to locals().
With an argument, equivalent to object.__dict__.

โอ้คน +100500
เคอร์บี

12

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

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

หากคุณกำลังมองหา "สิ่งที่มีค่าแอตทริบิวต์ไม่วัตถุของฉันมี?" แล้วdir()และ__dict__อาจจะเพียงพอ หากคุณกำลังมองหาสถานะปัจจุบันของออบเจกต์ตามอำเภอใจ (โปรดจำไว้ว่าในไพ ธ อนเกือบทุกอย่างเป็นออบเจกต์) แสดงว่าคุณinspectควรพิจารณาด้วย


ใช้คำอธิบายของคุณในการตรวจสอบเพื่อปรับปรุงคำตอบที่สมบูรณ์ที่สุด หวังว่าจะโอเคกับคุณ
Fernando César

9

มีฟังก์ชันในตัวเพื่อพิมพ์คุณสมบัติและค่าปัจจุบันของวัตถุทั้งหมดหรือไม่?

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

ดังนั้นข้อสรุปสั้น ๆ คือคุณสามารถเขียนของคุณเอง แต่มันจะคำนวณคุณสมบัติและตัวอธิบายข้อมูลที่คำนวณอื่น ๆ ซึ่งเป็นส่วนหนึ่งของ API สาธารณะและคุณอาจไม่ต้องการ:

from pprint import pprint
from inspect import getmembers
from types import FunctionType

def attributes(obj):
    disallowed_names = {
      name for name, value in getmembers(type(obj)) 
        if isinstance(value, FunctionType)}
    return {
      name: getattr(obj, name) for name in dir(obj) 
        if name[0] != '_' and name not in disallowed_names and hasattr(obj, name)}

def print_attributes(obj):
    pprint(attributes(obj))

มีปัญหากับคำตอบอื่น ๆ

สังเกตการใช้คำตอบที่ได้รับคะแนนสูงสุดในชั้นเรียนที่มีสมาชิกข้อมูลมากมาย:

from pprint import pprint

class Obj:
    __slots__ = 'foo', 'bar', '__dict__'
    def __init__(self, baz):
        self.foo = ''
        self.bar = 0
        self.baz = baz
    @property
    def quux(self):
        return self.foo * self.bar

obj = Obj('baz')
pprint(vars(obj))

พิมพ์เท่านั้น:

{'baz': 'baz'}

เนื่องจากvars จะส่งคืนเฉพาะ__dict__วัตถุเท่านั้นและไม่ใช่สำเนาดังนั้นหากคุณปรับเปลี่ยน dict ที่ส่งคืนโดย vars คุณจะต้องแก้ไข__dict__วัตถุเองด้วย

vars(obj)['quux'] = 'WHAT?!'
vars(obj)

ผลตอบแทน:

{'baz': 'baz', 'quux': 'WHAT?!'}

- ซึ่งไม่ดีเนื่องจาก quux เป็นคุณสมบัติที่เราไม่ควรตั้งค่าและไม่ควรอยู่ในเนมสเปซ ...

การใช้คำแนะนำในคำตอบที่ได้รับการยอมรับในปัจจุบัน (และอื่น ๆ ) นั้นไม่ค่อยดีเท่าไร:

>>> dir(obj)
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__slots__', '__str__', '__subclasshook__', 'bar', 'baz', 'foo', 'quux']

ในฐานะที่เราสามารถมองเห็นdirเพียงผลตอบแทนทั้งหมด (จริงเพียงมากที่สุด) ของชื่อที่เกี่ยวข้องกับวัตถุ

inspect.getmembersที่กล่าวถึงในความคิดเห็นมีข้อบกพร่องในทำนองเดียวกัน - มันจะส่งกลับชื่อและค่าทั้งหมด

ตั้งแต่ชั้นเรียน

เมื่อสอนฉันให้นักเรียนสร้างฟังก์ชั่นที่ให้ API ความหมายเชิงวัตถุ:

def api(obj):
    return [name for name in dir(obj) if name[0] != '_']

เราสามารถขยายสิ่งนี้เพื่อให้สำเนาของเนมสเปซซีแมนติกของวัตถุ แต่เราจำเป็นต้องแยก__slots__สิ่งที่ไม่ได้รับมอบหมายและหากเราทำการร้องขอสำหรับ "คุณสมบัติปัจจุบัน" อย่างจริงจังเราจำเป็นต้องแยกคุณสมบัติที่คำนวณได้ (เช่น อาจมีราคาแพงและสามารถตีความได้ว่าไม่ใช่ "ปัจจุบัน"):

from types import FunctionType
from inspect import getmembers

def attrs(obj):
     disallowed_properties = {
       name for name, value in getmembers(type(obj)) 
         if isinstance(value, (property, FunctionType))}
     return {
       name: getattr(obj, name) for name in api(obj) 
         if name not in disallowed_properties and hasattr(obj, name)}

และตอนนี้เราไม่ได้คำนวณหรือแสดงคุณสมบัติ, quux:

>>> attrs(obj)
{'bar': 0, 'baz': 'baz', 'foo': ''}

คำเตือน

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

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

ข้อสรุป

ไม่มีฟังก์ชั่นในตัวที่ทำสิ่งนี้และคุณควรทำสิ่งที่เหมาะสมที่สุดสำหรับสถานการณ์ของคุณ


FunctionTypeมีวงเล็บใกล้เพิ่มเติมหลังจากเป็น แต่มีประโยชน์มาก - ขอบคุณ!
nealmcb

@nealmcb ขอบคุณฉันคิดว่าฉันได้รับมัน ดีใจที่ได้บริการ! :)
Aaron Hall

7

ตัวอย่างการถ่ายโอนข้อมูลวัตถุการถ่ายโอนข้อมูลด้วยเวทมนตร์ :

$ cat dump.py
#!/usr/bin/python
import sys
if len(sys.argv) > 2:
    module, metaklass  = sys.argv[1:3]
    m = __import__(module, globals(), locals(), [metaklass])
    __metaclass__ = getattr(m, metaklass)

class Data:
    def __init__(self):
        self.num = 38
        self.lst = ['a','b','c']
        self.str = 'spam'
    dumps   = lambda self: repr(self)
    __str__ = lambda self: self.dumps()

data = Data()
print data

ไม่มีข้อโต้แย้ง:

$ python dump.py
<__main__.Data instance at 0x00A052D8>

ด้วยGnosis Utils :

$ python dump.py gnosis.magic MetaXMLPickler
<?xml version="1.0"?>
<!DOCTYPE PyObject SYSTEM "PyObjects.dtd">
<PyObject module="__main__" class="Data" id="11038416">
<attr name="lst" type="list" id="11196136" >
  <item type="string" value="a" />
  <item type="string" value="b" />
  <item type="string" value="c" />
</attr>
<attr name="num" type="numeric" value="38" />
<attr name="str" type="string" value="spam" />
</PyObject>

มันค่อนข้างล้าสมัย แต่ก็ยังใช้งานได้


6

หากคุณกำลังใช้สิ่งนี้เพื่อการดีบักและคุณเพียงต้องการดัมพ์ซ้ำของทุกสิ่งคำตอบที่ยอมรับนั้นไม่น่าพอใจเนื่องจากต้องการให้คลาสของคุณมี__str__การใช้งานที่ดีอยู่แล้ว หากไม่ใช่กรณีนี้จะได้ผลดีกว่า:

import json
print(json.dumps(YOUR_OBJECT, 
                 default=lambda obj: vars(obj),
                 indent=1))

นี้ไม่ได้ทำงานในหลาม 3. มีการติดตั้ง pymongo และทำมันเป็นคำตอบต่อ @Clark 's
ทิมโอกิลวี่

เช่นเดียวกับคำตอบอื่น ๆ อีกมากมายที่นี่TypeError: vars() argument must have __dict__ attribute
rob

6

ลอง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(), show_protected=True, show_static=True, show_properties=True)

เอาท์พุท:

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

สิ่งที่ฉันกำลังมองหาสำหรับการแก้ปัญหาอย่างรวดเร็ว :) พบที่ดี!
Joseph Astrahan

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

4
from pprint import pprint

def print_r(the_object):
    print ("CLASS: ", the_object.__class__.__name__, " (BASE CLASS: ", the_object.__class__.__bases__,")")
    pprint(vars(the_object))

4

สิ่งนี้จะพิมพ์เนื้อหาของวัตถุทั้งหมดซ้ำในรูปแบบเยื้อง json หรือ yaml:

import jsonpickle # pip install jsonpickle
import json
import yaml # pip install pyyaml

serialized = jsonpickle.encode(obj, max_depth=2) # max_depth is optional
print json.dumps(json.loads(serialized), indent=4)
print yaml.dump(yaml.load(serialized), indent=4)

4

ฉัน upvoted คำตอบที่กล่าวถึงเฉพาะ pprint เพื่อความชัดเจนหากคุณต้องการเห็นค่าทั้งหมดในโครงสร้างข้อมูลที่ซับซ้อนให้ทำดังนี้:

from pprint import pprint
pprint(my_var)

ที่my_varเป็นตัวแปรที่คุณสนใจ เมื่อฉันใช้pprint(vars(my_var))ฉันไม่ได้อะไรเลยและคำตอบอื่น ๆ ที่นี่ไม่ได้ช่วยหรือวิธีการดูยาวเกินความจำเป็น ในกรณีของฉันรหัสที่ฉันตรวจสอบมีพจนานุกรมพจนานุกรม

น่าจะชี้ให้เห็นว่าในบางคลาสที่กำหนดเองคุณอาจต้องจบด้วย<someobject.ExampleClass object at 0x7f739267f400>เอาต์พุตที่ไม่มีประโยชน์ ในกรณีนี้คุณอาจต้องใช้__str__วิธีการหรือลองใช้วิธีแก้ไขปัญหาอื่น ๆ ฉันยังต้องการค้นหาสิ่งที่เรียบง่ายที่ใช้งานได้ในทุกสถานการณ์โดยไม่มีห้องสมุดบุคคลที่สาม


3
> มีคลาสที่กำหนดเองบางส่วน ... นี่คือเหตุผลที่ฉันไม่ใช่แฟนของหลาม สิ่งที่ "บางครั้ง" ทำงานและ "บางครั้ง" ไม่ได้
AlxVallejo

3

ฉันต้องการพิมพ์ข้อมูล DEBUG ในบันทึกบางรายการและไม่สามารถใช้ pprint ได้เพราะมันจะทำให้แตก แต่ฉันทำอย่างนี้และได้สิ่งเดียวกัน

DO = DemoObject()

itemDir = DO.__dict__

for i in itemDir:
    print '{0}  :  {1}'.format(i, itemDir[i])

3

วิธีถ่ายโอนข้อมูล "myObject":

from bson import json_util
import json

print(json.dumps(myObject, default=json_util.default, sort_keys=True, indent=4, separators=(',', ': ')))

ฉันลองใช้ vars () และ dir (); ทั้งสองล้มเหลวในสิ่งที่ฉันกำลังมองหา vars () ไม่ทำงานเนื่องจากวัตถุไม่มี __dict__ (ข้อยกเว้น TypeError: vars () อาร์กิวเมนต์ต้องมีแอตทริบิวต์ __dict__) dir () ไม่ใช่สิ่งที่ฉันกำลังมองหา: มันเป็นเพียงรายการของชื่อเขตข้อมูลไม่ได้ให้ค่าหรือโครงสร้างวัตถุ

ฉันคิดว่า json.dumps () จะทำงานกับวัตถุส่วนใหญ่โดยไม่มีค่าเริ่มต้น = json_util.default แต่ฉันมีเขตข้อมูลวันที่ในวัตถุดังนั้นมาตรฐาน json serializer ล้มเหลว ดูวิธีเอาชนะ "datetime.datetime ไม่ใช่ JSON ต่อเนื่อง" ในหลาม?


โอเคต้องติดตั้ง pymongo tho เพื่อใช้งาน
ทิมโอกิลวี่

3

ทำไมไม่ง่าย ๆ :

for key,value in obj.__dict__.iteritems():
    print key,value

ไม่ควรจะเป็นอย่างนั้นfor key,value in obj.__dict__.iteritems(): print key,value?
Raz

2

pprintมี“ เครื่องพิมพ์ที่น่ารัก” สำหรับการสร้างโครงสร้างข้อมูลของคุณที่สวยงาม ฟอร์แมตเตอร์สร้างโครงสร้างข้อมูลที่สามารถแยกวิเคราะห์ได้อย่างถูกต้องโดยล่ามและยังง่ายต่อการอ่านของมนุษย์ เอาท์พุทจะถูกเก็บไว้ในบรรทัดเดียวถ้าเป็นไปได้และเยื้องเมื่อแยกข้ามหลายบรรทัด


2

เพียงแค่พยายามที่beeprint

มันจะช่วยให้คุณไม่เพียง แต่กับการพิมพ์ตัวแปรวัตถุ แต่ผลลัพธ์ที่สวยงามเช่นกัน:

class(NormalClassNewStyle):
  dicts: {
  },
  lists: [],
  static_props: 1,
  tupl: (1, 2)

1
โมดูลนี้ดูเหมือนจะไม่ได้รับการบำรุงรักษาอีกต่อไปและมีปัญหาเปิดจำนวนมาก ค่อนข้างใช้ppretty
Wavesailor

1

สำหรับทุกคนที่ดิ้นรนกับ

  • vars() ไม่ส่งคืนแอตทริบิวต์ทั้งหมด
  • dir() ไม่ส่งคืนค่าแอตทริบิวต์

รหัสต่อไปนี้พิมพ์คุณสมบัติทั้งหมดของobjด้วยค่าของพวกเขา:

for attr in dir(obj):
        try:
            print("obj.{} = {}".format(attr, getattr(obj, attr)))
        except AttributeError:
            print("obj.{} = ?".format(attr))

ไม่มีข้อผิดพลาด แต่ไม่สามารถเรียกซ้ำได้ดังนั้นให้รับที่อยู่ฐานสิบหกจำนวนมาก
ปล้น

0

คุณสามารถลองใช้ Flask Debug Toolbar
https://pypi.python.org/pypi/Flask-DebugToolbar

from flask import Flask
from flask_debugtoolbar import DebugToolbarExtension

app = Flask(__name__)

# the toolbar is only enabled in debug mode:
app.debug = True

# set a 'SECRET_KEY' to enable the Flask session cookies
app.config['SECRET_KEY'] = '<replace with a secret key>'

toolbar = DebugToolbarExtension(app)

0

ฉันชอบทำงานกับหลามออบเจกต์ชนิดคีย์หรือค่าต่างๆตัว

สำหรับแอตทริบิวต์โดยไม่คำนึงถึงว่าเป็นวิธีการหรือตัวแปร:

o.keys()

สำหรับค่าของคุณลักษณะเหล่านั้น:

o.values()

0

สิ่งนี้ใช้งานได้ไม่ว่าจะกำหนด varibles ของคุณอย่างไรภายในคลาสภายใน __init__ หรือภายนอก

your_obj = YourObj()
attrs_with_value = {attr: getattr(your_obj, attr) for attr in dir(your_obj)}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.