したがって、ここで探しているのは、PHPのprint_r関数のようなものです。
これは、問題のオブジェクトの状態を確認することでスクリプトをデバッグできるようにするためです。
したがって、ここで探しているのは、PHPのprint_r関数のようなものです。
これは、問題のオブジェクトの状態を確認することでスクリプトをデバッグできるようにするためです。
vars()
と混ぜたいpprint()
:
from pprint import pprint
pprint(vars(your_object))
あなたは本当に2つの異なるものを混ぜ合わせています。
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__'}
def dump(obj):
for attr in dir(obj):
print("obj.%s = %r" % (attr, getattr(obj, attr)))
作成者の好みに応じて、例外処理、国別/特殊文字の印刷、ネストされたオブジェクトへの再帰などを追加する多くのサードパーティ関数があります。しかし、それらはすべて基本的にこれに要約されます。
dir
が言及されていますが、それは属性の名前のみを提供します。それらの値も必要な場合は、 を試してください__dict__
。
class O:
def __init__ (self):
self.value = 3
o = O()
出力は次のとおりです。
>>> o.__dict__
{'value': 3}
これを行うには、「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']
>>>
もう 1 つの便利な機能はヘルプです。
>>> 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
オブジェクトの現在の状態を出力するには、次のようにします。
>>> obj # in an interpreter
また
print repr(obj) # in a script
また
print obj
クラスの定義__str__
または__repr__
メソッド。Pythonのドキュメントから:
__repr__(self)
repr()
オブジェクトの「正式な」文字列表現を計算するために、組み込み関数および文字列変換 (逆引用符) によって呼び出されます。可能であれば、これは同じ値を持つオブジェクトを再作成するために使用できる有効な Python 式のように見えるはずです (適切な環境が与えられた場合)。これが不可能な場合は、「<...便利な説明...>」という形式の文字列を返す必要があります。戻り値は文字列オブジェクトでなければなりません。クラスがrepr () を定義していて を定義していない場合、そのクラスのインスタンスの「非形式的な」文字列表現が必要な場合にも__str__()
thenが使用されます。__repr__()
これは通常、デバッグに使用されるため、情報が豊富で明確な表現であることが重要です。
__str__(self)
str()
オブジェクトの「非公式」文字列表現を計算するために、組み込み関数および print ステートメントによって呼び出されます。__repr__()
これは、有効な Python 式である必要がないという点で とは異なります。代わりに、より便利で簡潔な表現を使用できます。戻り値は文字列オブジェクトでなければなりません。
チェックする価値があるかもしれません-
PerlのData::Dumperに相当するPythonはありますか?
私の推薦はこれです-
https://gist.github.com/1071857
perlにはData::Dumperというモジュールがあり、オブジェクトデータをperlソースコードに変換します(注:コードをソースに変換しません。ほとんどの場合、出力でオブジェクトメソッド関数を使用する必要はありません)。これは永続化に使用できますが、一般的な目的はデバッグです。
標準のpythonpprintが達成できないことはたくさんあります。特に、オブジェクトのインスタンスを見ると下降を停止し、オブジェクトの内部16進ポインターを提供します(エラー、そのポインターは、道)。つまり、一言で言えば、Pythonはこの優れたオブジェクト指向パラダイムに関するものですが、箱から出してすぐに使えるツールは、オブジェクト以外のものを操作するために設計されています。
perl Data :: Dumperを使用すると、移動する深さを制御でき、循環リンク構造を検出することもできます(これは非常に重要です)。このプロセスは、オブジェクトがその祝福を超えて特別な魔法を持っていないため、基本的にperlで達成するのが簡単です(普遍的に明確に定義されたプロセス)。
を使用することをお勧めし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__.
ほとんどの場合、__dict__
orを使用dir()
すると、必要な情報が得られます。さらに詳細が必要な場合は、標準ライブラリにinspectモジュールが含まれており、印象的な量の詳細を取得できます。情報の本当のナゲットのいくつかは次のとおりです。
「私のオブジェクトが持っている属性値は何か?」だけを探している場合は、おそらくdir()
and__dict__
で十分です。任意のオブジェクトの現在の状態を本当に掘り下げたい場合 (Python ではほとんどすべてがオブジェクトであることに注意してください)、inspect
検討する価値があります。
これをデバッグに使用していて、すべての再帰的なダンプが必要な場合は、クラスに適切な__str__
実装が既に必要なため、受け入れられた答えは満足のいくものではありません。そうでない場合、これははるかにうまく機能します:
import json
print(json.dumps(YOUR_OBJECT,
default=lambda obj: vars(obj),
indent=1))
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)
メタプログラミングの例Dump object with magic :
$ 猫のダンプ.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 ダンプ.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>
少し古くなっていますが、まだ機能しています。
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))
これにより、すべてのオブジェクトの内容が 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)
簡単なことではない理由:
for key,value in obj.__dict__.iteritems():
print key,value
これは、変数がクラス内、 __init__ 内、または外部でどのように定義されていても機能します。
your_obj = YourObj()
attrs_with_value = {attr: getattr(your_obj, attr) for attr in dir(your_obj)}
pprintには、データ構造の見た目に美しい表現を作成するための「きれいなプリンター」が含まれています。フォーマッターは、インタープリターが正しく解析でき、人間が読みやすいデータ構造の表現を生成します。可能であれば、出力は1行に保持され、複数行に分割されるとインデントされます。
beeprintを試してみてください。
オブジェクト変数の出力だけでなく、次のような美しい出力にも役立ちます。
class(NormalClassNewStyle):
dicts: {
},
lists: [],
static_props: 1,
tupl: (1, 2)