Python を使用したさまざまなプロジェクト (Django Web 開発や Panda3D ゲーム開発など) でコーディングを開始しています。
何が起こっているのかを理解するのを助けるために、基本的にPythonオブジェクトの内部を「見て」、メソッドやプロパティなど、オブジェクトがどのように動いているかを確認したいと思います。
Python オブジェクトがあるとします。その内容を出力するには何が必要でしょうか? それは可能ですか?
Python を使用したさまざまなプロジェクト (Django Web 開発や Panda3D ゲーム開発など) でコーディングを開始しています。
何が起こっているのかを理解するのを助けるために、基本的にPythonオブジェクトの内部を「見て」、メソッドやプロパティなど、オブジェクトがどのように動いているかを確認したいと思います。
Python オブジェクトがあるとします。その内容を出力するには何が必要でしょうか? それは可能ですか?
object.__dict__
まだ誰もヘルプについて言及していないことに驚いています!
In [1]: def foo():
...: "foo!"
...:
In [2]: help(foo)
Help on function foo in module __main__:
foo()
foo!
ヘルプを使用すると、docstring を読んで、クラスが持つ可能性のある属性を把握できます。これは非常に役立ちます。
まず、ソースを読んでください。
次に、dir()
関数を使用します。
これが何が起こっているのかを調べるための調査である場合は、 IPythonを見ることをお勧めします。これにより、オブジェクトのドキュメント、プロパティ、さらにはソース コードを取得するためのさまざまなショートカットが追加されます。たとえば、「?」を追加します。オブジェクトのヘルプを表示します (実質的には "help(obj)" のショートカットですが、2 つの ? (" func??
") を使用すると、利用可能な場合はソースコードが表示されます)。
また、タブ補完、結果のきれいな印刷、結果履歴など、この種の探索的プログラミングに非常に便利な追加の便利な機能がたくさんあります。
イントロスペクションをよりプログラム的に使用するにはdir()
、vars()
、などの基本的なビルトインが役立ちますが、時間をかけてinspectモジュール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
また、関数パラメータの名前とデフォルト値を提供するため、関数のラッピングまたは操作を行う場合にも役立ちます。
このための GUI に興味がある場合は、objbrowserをご覧ください。下にあるオブジェクトのイントロスペクションには、Python 標準ライブラリの inspect モジュールを使用します。
シェルで 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
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
)
"""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__
他の人は、探しているもののように聞こえる dir() ビルトインについて既に言及していますが、ここに別の良いヒントがあります。標準ライブラリのほとんどを含む多くのライブラリは、ソース形式で配布されています。つまり、ソースコードを直接簡単に読むことができます。秘訣はそれを見つけることです。例えば:
>>> import string
>>> string.__file__
'/usr/lib/python2.5/string.pyc'
*.pyc ファイルはコンパイルされているので、末尾の 'c' を削除し、お気に入りのエディターまたはファイル ビューアーで未コンパイルの *.py ファイルを開きます。
/usr/lib/python2.5/string.py
これは、特定の API からどの例外が発生したかなどを発見するのに非常に役立つことがわかりました。この種の詳細は、Python の世界ではほとんど文書化されていません。
パラメータとメソッドを見たい場合は、他の人が指摘したように、pprint
またはdir()
コンテンツの実際の値を確認したい場合は、次のことができます
object.__dict__
この目的のためだけに構築された Python コード ライブラリがあります: inspect Python 2.7 で導入
pprint と dir を一緒に使うとうまくいきます
ライブオブジェクトの内部を見たい場合は、python のinspect
モジュールが良い答えです。一般に、ディスク上のどこかにあるソース ファイルで定義されている関数のソース コードを取得するために機能します。dill.source.getsource
インタープリターで定義されたライブ関数とラムダのソースを取得する場合は、 fromを使用できますdill
。また、カレーで定義されたバインドまたはアンバインド クラス メソッドおよび関数からコードを取得することもできます。
>>> 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
>>>
さらに、リストと辞書の中を見たい場合は、 pprint() を使用できます