Answers:
您实际上是将两种不同的东西混合在一起。
使用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__'}
print re.compile(r'slots').search('No slots here either.').__slots__
inspect
答案中更多地谈论模块?我认为这是最接近print_r或var_dump的东西。
dir()
?dir()
仅返回名称列表,并且并非所有名称都存在于属性中vars()
或__dict__
属性中。
您要vars()
与pprint()
:
from pprint import pprint
pprint(vars(your_object))
dir()
为您提供所有您可能不喜欢__str__
和喜欢的内置东西__new__
。var()
没有。
__dict__
属性的对象上失败。
def dump(obj):
for attr in dir(obj):
print("obj.%s = %r" % (attr, getattr(obj, attr)))
有很多第三方函数可以根据其作者的喜好添加诸如异常处理,国家/特殊字符打印,递归到嵌套对象等功能。但他们基本上都归结为这一点。
getmembers()
在标准inspect
模块中使用该功能,但我认为这样做会更有用,因为它说明了如何进行自省。
__dict__
(例如__doc__
和__module__
)。此外,__dict__
对于使用声明的对象根本不起作用__slots__
。通常,__dict__
显示实际上存储在内部字典中的用户级属性。dir()显示更多。
__dict__
属性/成员。我知道这很疯狂,但事实如此。内置像int
和str
或re.MatchObject
s是常见示例。尝试'hello'.__dict__
,然后尝试dir('hello')
已经提到了dir,但这只会为您提供属性的名称。如果还需要它们的值,请尝试__dict__。
class O:
def __init__ (self):
self.value = 3
o = O()
这是输出:
>>> o.__dict__
{'value': 3}
set
这样的对象没有__dict__
,所以对他们来说,它将失败AttributeError: 'set' object has no attribute '__dict__'
您可以使用“ 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
要打印对象的当前状态,您可以:
>>> 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()
内置函数和print语句调用,以计算对象的“非正式”字符串表示形式。区别__repr__()
在于它不必是有效的Python表达式:相反,可以使用更方便或更简洁的表示形式。返回值必须是一个字符串对象。
print "DEBUG: object value: " + repr(obj)
可能值得一看-
是否有与Perl的Data :: Dumper等效的Python?
我的建议是
https://gist.github.com/1071857
请注意,perl有一个称为Data :: Dumper的模块,该模块将对象数据转换回perl源代码(注意:它不会将代码转换回源代码,并且几乎始终不希望输出中的对象方法函数)。可以将其用于持久性,但通用目的是用于调试。
标准python pprint有很多无法实现的功能,特别是当它看到一个对象的实例并为您提供该对象的内部十六进制指针时,它只会停止下降(错误,该指针不是很多使用方式)。简而言之,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__.
是否有内置功能可以打印对象的所有当前属性和值?
不可以。最受好评的答案不包括某些类型的属性,被接受的答案显示了如何获取所有属性,包括非公共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__
对象的,而并非副本,因此,如果您修改vars返回的dict,那么您也将修改__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
。但是非常有帮助-谢谢!
$ 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实用程序:
$ 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))
TypeError: vars() argument must have __dict__ attribute
尝试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)
这将以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)
我赞成仅提及pprint的答案。明确地说,如果要查看复杂数据结构中的所有值,请执行以下操作:
from pprint import pprint
pprint(my_var)
其中my_var是您感兴趣的变量。当我使用时,pprint(vars(my_var))
我什么也没得到,这里的其他答案也无济于事,或者该方法看起来不必要地冗长。顺便说一句,在我的特定情况下,我正在检查的代码具有字典词典。
值得指出的是,对于某些自定义类,您可能只会得到无用<someobject.ExampleClass object at 0x7f739267f400>
的输出。在这种情况下,您可能必须实现一个__str__
方法或尝试其他解决方案。我仍然想找到没有第三方库就可以在所有情况下使用的简单方法。
要转储“ 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__(exceptions.TypeError:vars()参数必须具有__dict__属性)。dir()并不是我要找的东西:它只是字段名的列表,不提供值或对象结构。
我认为json.dumps()适用于没有default = json_util.default的大多数对象,但是我在对象中有一个datetime字段,因此标准json序列化程序失败。请参阅如何克服python中的“ datetime.datetime无法JSON序列化”?
只需尝试beeprint。
它不仅可以帮助您打印对象变量,而且还可以帮助您输出漂亮的输出,例如:
class(NormalClassNewStyle):
dicts: {
},
lists: [],
static_props: 1,
tupl: (1, 2)
您可以尝试Flask调试工具栏。
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)
__dict__
成员(re.MatchObject
例如,一个成员),但是内建函数dir()
可用于所有对象。