Làm thế nào để tôi nhìn vào bên trong một đối tượng Python?


291

Tôi đang bắt đầu viết mã trong các dự án khác nhau bằng Python (bao gồm phát triển web Django và phát triển trò chơi Panda3D).

Để giúp tôi hiểu những gì đang diễn ra, về cơ bản tôi muốn 'nhìn' bên trong các đối tượng Python để xem cách chúng đánh dấu - như các phương thức và thuộc tính của chúng.

Vì vậy, nói rằng tôi có một đối tượng Python, tôi cần gì để in ra nội dung của nó? Điều đó thậm chí có thể?

Câu trả lời:


352

Python có một bộ tính năng hướng nội mạnh mẽ.

Hãy xem các chức năng tích hợp sau:

type()dir()đặc biệt hữu ích cho việc kiểm tra loại đối tượng và tập hợp các thuộc tính của nó, tương ứng.


25
Không biết thuật ngữ này là 'hướng nội'. Đó là một sự trợ giúp tuyệt vời! Cũng như tất cả các functon bạn đã cho tôi ... Cảm ơn bạn!
littlejim84

2
thuộc tính, classmethod và staticmethod không liên quan đến hướng nội. Các phương thức này đều tạo ra các loại đối tượng đặc biệt có thể được sử dụng để định nghĩa các lớp có hành vi đặc biệt, nhưng không giúp ích gì trong việc kiểm tra các lớp hoặc cấu trúc đó.
SingleNegationElimination

Câu trả lời từ @Brian dưới đây cho bạn thấy cách xem mã nguồn của các đối tượng python khác nhau từ bên trong python. Đó là những gì tôi đã tìm kiếm ban đầu và tôi chắc chắn rằng tôi sẽ không cô đơn. (Có thể đáng để bao gồm một tham chiếu đến câu trả lời của anh ấy trong câu trả lời này vì nó được chấp nhận nhiều nhất.)
michaelavila

Nó giống như "IntelliSense" tích hợp cho python. Tôi thích nó.
Bruno Bieri

7
Tôi nghĩ rằng đó là một câu trả lời xấu. thay vì cung cấp cho chúng tôi một giải pháp, nó chỉ cung cấp cho chúng tôi mọi thứ liên quan đến tài liệu đó
Ishan Srivastava

176

object.__dict__


12
vars(object)được làm cho điều đó.
lực lượng tự do

6
Trên thực tế from pprint import pprint; pprint(vars(object))đã cho tôi một cái nhìn thực sự tốt đẹp về nội dung của đối tượng của tôi. Cảm ơn @liberforce
N. Maks

cách tốt nhất để xem đối tượng và nội dung của nó trong một chuỗi
Peter Krauss

Đây là một cách tuyệt vời để xem các đối tượng thực hiện bất kỳ phương thức đại diện nào hoặc các đối tượng như googleapiclient.errors.HttpError mà khi bạn in chúng, chúng sẽ in không đủ thông tin, cảm ơn @ mtasic85
Felipe Valdes

65

Đầu tiên, đọc nguồn.

Thứ hai, sử dụng dir()chức năng.


92
Tôi sẽ đảo ngược thứ tự đó.
bayer

5
Nguồn có nhiều thông tin hơn dir () và một thói quen tốt hơn để phát triển.
S.Lott

14
Tôi có ý kiến ​​khác. dir () nhanh hơn rất nhiều và trong 99% trường hợp, hãy để bạn tìm hiểu những gì bạn cần kết hợp với trợ giúp ().
bayer

7
Tôi đồng ý với thường xuyên. Rất nhiều thời gian, một cuộc gọi đơn giản đến dir () sẽ đủ, do đó tiết kiệm cho bạn những rắc rối khi phải xem qua mã nguồn.
Sasha Chedygov

3
Đôi khi kiểm tra các đối tượng trong thời gian chạy có thể hữu ích nhưng đọc nguồn thì không. Ví dụ: các lớp omeplib.py và phương thức của họ :).
Denis Barmenkov

61

Tôi ngạc nhiên không có ai đề cập đến sự giúp đỡ nào!

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

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

foo()
    foo!

Trợ giúp cho phép bạn đọc chuỗi tài liệu và có ý tưởng về các thuộc tính mà một lớp có thể có, điều này khá hữu ích.


Sau đó, bạn sử dụng các kỹ thuật khác được đề cập ở đây. Nhưng nếu tài liệu có sẵn, hãy xem nó là canon.
Edward Falk

Tôi không chắc liệu python có cập nhật chức năng này trong vài năm qua không, nhưng "help (object_name)" cung cấp một cái nhìn tổng quan đầy đủ trong một định dạng có cấu trúc cao. Đó là một người giữ. Cảm ơn.
Brian Cugelman

27

Nếu đây là để khám phá để xem những gì đang diễn ra, tôi khuyên bạn nên xem IPython . Điều này thêm các phím tắt khác nhau để có được một tài liệu đối tượng, thuộc tính và thậm chí mã nguồn. Ví dụ: nối thêm "?" đến một chức năng sẽ cung cấp trợ giúp cho đối tượng (thực sự là một phím tắt cho "help (obj)", các máy ảnh sử dụng hai? '(" func??") sẽ hiển thị mã nguồn nếu nó khả dụng.

Ngoài ra còn có rất nhiều tiện ích bổ sung, như hoàn thành tab, in ấn kết quả đẹp, lịch sử kết quả, vv làm cho nó rất tiện dụng cho loại lập trình khám phá này.

Để sử dụng chương trình hơn mẫn, các lệnh nội trú cơ bản thích dir(), vars(), getattrvv sẽ hữu ích, nhưng nó cũng có giá trị thời gian của bạn để kiểm tra , kiểm tra mô-đun. Để tìm nạp nguồn của hàm, sử dụng " inspect.getsource" ví dụ: áp dụng nó cho chính nó:

>>> 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 cũng thường hữu ích nếu bạn đang xử lý các gói hoặc thao tác các hàm, vì nó sẽ cung cấp tên và giá trị mặc định của các tham số hàm.


18

Nếu bạn quan tâm đến GUI cho việc này, hãy xem objbrowser . Nó sử dụng mô-đun kiểm tra từ thư viện chuẩn Python cho phần hướng nội của đối tượng bên dưới.

objbrowsersc mãi


9

Bạn có thể liệt kê các thuộc tính của một đối tượng với dir () trong shell:

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

Tất nhiên, cũng có mô-đun kiểm tra: http://docs.python.org/l 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
Điều này hoạt động tốt trong python 3 nếu bạn chỉ cần thêm parens xung quanh bản in.
ConstantineK

8

thử 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)

Đầu ra:

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

7

Những người khác đã đề cập đến dir () tích hợp có âm thanh giống như những gì bạn đang tìm kiếm, nhưng đây là một mẹo hay khác. Nhiều thư viện - bao gồm hầu hết các thư viện chuẩn - được phân phối ở dạng nguồn. Có nghĩa là bạn có thể dễ dàng đọc mã nguồn trực tiếp. Bí quyết là trong việc tìm kiếm nó; ví dụ:

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

Tệp * .pyc được biên dịch, vì vậy hãy xóa dấu 'c' và mở tệp * .py chưa được biên dịch trong trình chỉnh sửa hoặc trình xem tệp yêu thích của bạn:

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

Tôi đã thấy điều này cực kỳ hữu ích để khám phá những thứ như ngoại lệ được nêu ra từ một API nhất định. Loại chi tiết này hiếm khi được ghi chép lại trong thế giới Python.


7

Trong khi pprintđã được đề cập bởi những người khác, tôi muốn thêm một số bối cảnh.

Mô-đun pprint cung cấp một khả năng cho các cấu trúc dữ liệu Python tùy ý in ấn ở một dạng có thể được sử dụng làm đầu vào cho trình thông dịch. Nếu các cấu trúc được định dạng bao gồm các đối tượng không phải là loại Python cơ bản, thì biểu diễn có thể không tải được. Đây có thể là trường hợp nếu các đối tượng như tệp, ổ cắm, lớp hoặc thể hiện được bao gồm, cũng như nhiều đối tượng tích hợp khác không thể biểu thị như hằng số Python.

pprint có thể có nhu cầu cao bởi các nhà phát triển có nền tảng PHP đang tìm kiếm một giải pháp thay thế cho var_dump() .

Các đối tượng có thuộc tính dict có thể được kết xuất độc đáo bằng cách sử dụng pprint()trộn với vars(), trả về __dict__thuộc tính cho mô-đun, lớp, thể hiện, v.v.:

from pprint import pprint
pprint(vars(your_object))

Vì vậy, không cần một vòng lặp .

Để kết xuất tất cả các biến có trong phạm vi toàn cầu hoặc cục bộ, chỉ cần sử dụng:

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

locals()hiển thị các biến được định nghĩa trong một hàm.
Nó cũng hữu ích để truy cập các hàm với tên tương ứng của chúng dưới dạng khóa chuỗi, trong số các cách sử dụng khác :

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

Tương tự, sử dụng dir() để xem nội dung của một mô-đun hoặc các thuộc tính của một đối tượng.

Và vẫn còn nhiều hơn nữa.


4

Nếu bạn muốn xem xét các tham số và phương thức, như những người khác đã chỉ ra rằng bạn cũng có thể sử dụng pprinthoặcdir()

Nếu bạn muốn xem giá trị thực của nội dung, bạn có thể làm

object.__dict__


4

Hai công cụ tuyệt vời để kiểm tra mã là:

  1. IPython . Một thiết bị đầu cuối python cho phép bạn kiểm tra bằng cách sử dụng hoàn thành tab.

  2. Eclipse với plugin PyDev . Nó có một trình gỡ lỗi tuyệt vời cho phép bạn phá vỡ tại một điểm nhất định và kiểm tra các đối tượng bằng cách duyệt tất cả các biến dưới dạng cây. Bạn thậm chí có thể sử dụng thiết bị đầu cuối nhúng để thử mã tại điểm đó hoặc nhập đối tượng và nhấn '.' để có nó đưa ra gợi ý mã cho bạn.

nhập mô tả hình ảnh ở đây



3

Có một bản dựng thư viện mã python chỉ dành cho mục đích này: kiểm tra Được giới thiệu trong Python 2.7


3

Nếu bạn muốn xem mã nguồn của hàm tương ứng với đối tượng myobj, bạn có thể nhập iPythonhoặc Jupyter Notebook:

myobj??


2
import pprint

pprint.pprint(obj.__dict__)

hoặc là

pprint.pprint(vars(obj))

Mặc dù mã này có thể trả lời câu hỏi, việc cung cấp ngữ cảnh bổ sung về cách thức và / hoặc lý do giải quyết vấn đề sẽ cải thiện giá trị lâu dài của câu trả lời.
Alexander

1

Nếu bạn muốn nhìn vào bên trong một vật thể sống, thì inspectmô-đun của python là một câu trả lời tốt. Nói chung, nó hoạt động để lấy mã nguồn của các hàm được xác định trong tệp nguồn ở đâu đó trên đĩa. Nếu bạn muốn lấy nguồn của hàm sống và lambdas đã được xác định trong trình thông dịch, bạn có thể sử dụng dill.source.getsourcetừ đó dill. Nó cũng có thể lấy mã từ các phương thức và hàm lớp bị ràng buộc hoặc không ràng buộc được xác định trong các dòng chữ ... tuy nhiên, bạn có thể không thể biên dịch mã đó mà không có mã của đối tượng kèm theo.

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

Ngoài ra, nếu bạn muốn xem danh sách bên trong và từ điển, bạn có thể sử dụng pprint ()


0

Nhiều mẹo hay đã có, nhưng ngắn nhất và dễ nhất (không nhất thiết là tốt nhất) vẫn chưa được đề cập:

object?

-3

Hãy thử sử dụng:

print(object.stringify())
  • đâu objectlà tên biến của đối tượng bạn đang cố kiểm tra.

Điều này in ra một đầu ra được định dạng và được định dạng độc đáo hiển thị tất cả phân cấp các khóa và giá trị trong đối tượng.

LƯU Ý: Điều này hoạt động trong python3. Không chắc chắn nếu nó hoạt động trong các phiên bản trước

CẬP NHẬT: Điều này không hoạt động trên tất cả các loại đối tượng. Nếu bạn gặp một trong những loại đó (như đối tượng Yêu cầu), hãy sử dụng một trong các loại sau:

  • dir(object())

hoặc là

import pprint sau đó: pprint.pprint(object.__dict__)


1
Không hoạt động trên một đối tượng 'Yêu cầu' "Đối tượng 'Yêu cầu' không có thuộc tính '
chuỗi hóa
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.