私がここで探しているのは、PHPの print_r 関数のようなものです。これは、問題のオブジェクトの状態を確認することでスクリプトをデバッグできるようにするためです。
あなたは本当に二つの異なることを混ぜ合わせています。
興味のあるものを取得するには、 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__'}
vars()
をpprint()
と混在させる必要があります。
from pprint import pprint
pprint(vars(your_object))
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}
オブジェクトの現在の状態を表示するには、次のようにします。
>>> obj # in an interpreter
または
print repr(obj) # in a script
または
print obj
あなたのクラスのために__str__
または__repr__
メソッドを定義してください。 Pythonのドキュメントから :
__repr__(self)
repr()
組み込み関数と、オブジェクトの "正式な"文字列表現を計算するための文字列変換(逆引用符)によって呼び出されます。可能であれば、これは(適切な環境で)同じ値を持つオブジェクトを再作成するために使用できる有効なPython式のように見えるはずです。それが不可能な場合は、 "<... some useful description ...>"の形式の文字列を返すべきです。戻り値は文字列オブジェクトでなければなりません。クラスが repr ()を定義し、__str__()
を定義しない場合、そのクラスのインスタンスの「非公式な」文字列表現が必要なときにも__repr__()
が使用されます。これは通常デバッグに使用されるので、表現は情報が豊富で明確であることが重要です。
__str__(self)
組み込み関数str()
とprint文によって呼び出され、オブジェクトの「非公式」な文字列表現を計算します。これは有効なPython式である必要はないという点で__repr__()
と異なります。代わりに、より便利な表現または簡潔な表現を使用できます。戻り値は文字列オブジェクトでなければなりません。
これを行うには "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
チェックする価値があるかもしれません -
PerlのData :: Dumperに相当するPythonはありますか?
私のおすすめはこれです -
https://Gist.github.com/1071857
Perlには、オブジェクトデータをPerlのソースコードに変換するData :: Dumperというモジュールがあります(NB:コードをソースに変換し直すことはありません。ほとんどの場合、出力のオブジェクトメソッド関数は使用したくありません)。これは永続化に使用できますが、共通の目的はデバッグ用です。
標準のpython pprintでは達成できないことがたくさんあります。特に、オブジェクトのインスタンスを見て、オブジェクトの内部16進数ポインタを渡すと、降順で止まるだけです(errr。このポインタは、あまり使用されていません)。道)。一言で言えば、pythonはこの素晴らしいオブジェクト指向パラダイムのすべてですが、箱から出して使えるツールはオブジェクト以外のもので作業するために設計されています。
PerlのData :: Dumperは、あなたがどれだけ深く行きたいのかを制御することを可能にし、また循環リンク構造を検出します(それは本当に重要です)。オブジェクトは祝福を超えて特別な魔法を持っているわけではないので(普遍的に明確に定義されたプロセス)、このプロセスは基本的にPerlで達成するのがより簡単です。
ほとんどの場合、__dict__
またはdir()
を使用すると、必要な情報が得られます。もっと詳細が必要な場合は、標準ライブラリに inspect モジュールが含まれています。これを使用すると、かなり詳細な情報を取得できます。情報の本当の意味は次のとおりです。
「自分のオブジェクトにはどの属性値がありますか?」を探しているだけなら、おそらくdir()
と__dict__
で十分です。任意のオブジェクトの現在の状態を掘り下げることを本当に検討している場合(pythonではほとんどすべてがオブジェクトであることに留意してください)、inspect
を検討する価値があります。
メタプログラミングの例 オブジェクトをマジックダンプします :
$ 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>
少し古くなっていますが、まだ機能しています。
これをデバッグに使用していて、すべてを再帰的にダンプしたいだけの場合は、クラスに__str__
実装が既に必要であるため、受け入れられた答えは不十分です。そうでない場合は、これがはるかにうまく機能します。
import json
print(json.dumps(YOUR_OBJECT,
default=lambda obj: vars(obj),
indent=1))
これはすべてのオブジェクトの内容を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)
"myObject"をダンプするには
from bson import json_util
import json
print(json.dumps(myObject, default=json_util.default, sort_keys=True, indent=4, separators=(',', ': ')))
私はvars()とdir()を試しました。どちらも私が探していたものに失敗しました。オブジェクトに__dict__がないため、vars()は機能しませんでした(exceptions.TypeError:vars()引数には__dict__属性が必要です)。 dir()は私が探していたものではありませんでした。それは単にフィールド名のリストであり、値もオブジェクト構造も与えていません。
Default = json_util.defaultがなくてもjson.dumps()はほとんどのオブジェクトでうまくいくと思いますが、オブジェクトにdatetimeフィールドがあるため、標準のjsonシリアライザは失敗しました。 pythonで "datetime.datetimeがJSONのシリアライズ可能ではない"を克服するにはどうすればいいですか? を参照してください。
試してみる 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)
私は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__.
私はいくつかのログにDEBUG情報を印刷する必要があり、それが壊れるのでpprintを使用することができませんでした。代わりに私はこれをして、そして事実上同じことを得ました。
DO = DemoObject()
itemDir = DO.__dict__
for i in itemDir:
print '{0} : {1}'.format(i, itemDir[i])
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))
単純ではない理由
for key,value in obj.__dict__.iteritems():
print key,value
pprint はあなたのデータ構造の審美的に満足のいく表現を作り出すための「かわいいプリンタ」を含みます。フォーマッタは、インタプリタによって正しく解析されることができるデータ構造の表現を生成します、そしてまた人間にとって読みやすいです。可能であれば、出力は単一行に保たれ、複数行にまたがって分割されると字下げされます。
beeprint を試してください。
これは、印刷オブジェクト変数だけでなく、このように美しい出力にも役立ちます。
class(NormalClassNewStyle):
dicts: {
},
lists: [],
static_props: 1,
tupl: (1, 2)
私はpprintだけを述べている答えを支持しました。明確にするために、複雑なデータ構造ですべての values を表示したい場合は、次のようにします。
from pprint import pprint
pprint(my_var)
my_var は、あなたが興味を持っている変数です。 pprint(vars(my_var))を使用しても何も得られませんでした。その他の回答では役に立ちませんでした。または、メソッドが不必要に長く見えました。ところで、私の特定のケースでは、私が調べていたコードは辞書の辞書を持っていました。
いくつかのカスタムクラスでは、役に立たない<someobject.ExampleClass object at 0x7f739267f400>
のような出力になってしまうかもしれないことを指摘する価値があります。その場合は、__str__
メソッドを実装するか、他の解決策を試す必要があります。サードパーティのライブラリがなくても、すべてのシナリオで機能するシンプルなものを見つけたいと思います。
苦しんでいる皆さんのために
vars()
はすべての属性を返しません。dir()
は属性の値を返しません。次のコードは、obj
の all 属性をその値とともに出力します。
for attr in dir(obj):
try:
print("obj.{} = {}".format(attr, getattr(obj, attr)))
except AttributeError:
print("obj.{} = ?".format(attr))
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)