这里我要找的是PHP的print_r函数。
这样我就可以通过查看有问题的对象的状态来调试脚本。
这里我要找的是PHP的print_r函数。
这样我就可以通过查看有问题的对象的状态来调试脚本。
当前回答
我没有测试过性能,但我相信这是在Python中以列表形式枚举任何对象的属性/属性/键的最快方法。
# If core==False, ignore __k__ entries
def obj_props(obj, core=False) -> list:
assert not obj is None, f"obj must not be null (None)"
_props = []
_use_dir=False
def _add(p):
if not core and p.find('__') == 0: return
_props.append(p)
if hasattr(obj, '__dict__'):
for p in obj.__dict__.keys(): _add(p)
elif hasattr(obj, '__slots__'):
for p in obj.__slots__: _add(p)
elif hasattr(obj, 'keys'):
try:
for p in obj.keys(): _add(p)
except Exception as ex:
_props = []
_use_dir = True
else:
_use_dir = True
if _use_dir:
# fall back to slow and steady
for p in dir(obj):
if not core and p.find('__') == 0: continue
v = getattr(obj, p)
v_t = type(v).__name__
if v_t in ('function', 'method', 'builtin_function_or_method', 'method-wrapper'): continue
_props.append(p)
return _props
上面应该适用于常规的python对象(使用__dict__),使用插槽的对象(__slots__),甚至适用于像对象一样的字典。
大多数其他示例使用dir(obj),它将枚举对象的所有方法和属性,如果您只需要它的属性,则会对性能造成影响。
其他回答
从答案中,可以稍微修改一下,只得到一个对象的“Attributes”,如下所示:
def getAttributes(obj):
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 for name in dir(obj)
if name[0] != '_' and name not in disallowed_names and hasattr(obj, name)}
pprint(attributes(obj))
在临时添加此函数时非常有用,并且可以在不修改现有源代码的情况下删除此函数
尝试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)
一个有魔力的元编程示例转储对象:
$ 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>
虽然有点过时,但还能用。
要打印对象的当前状态,你可以:
>>> obj # in an interpreter
or
print repr(obj) # in a script
or
print obj
为你的类定义__str__或__repr__方法。来自Python文档:
__repr__(self)由repr()内置函数调用,由字符串调用 转换(反引号)到 计算“官方”字符串 对象的表示。如果有的话 可能,这看起来像a 有效的Python表达式 方法重新创建对象 相同的值(给定一个合适的 环境)。如果不可能, 形式为“<…一些有用的 描述……应该返回>。 返回值必须为字符串 对象。如果一个类定义了repr() 但不是__str__(),则__repr__()是 也用于“非正式”字符串 实例的表示 班级是必需的。这是典型的 用于调试,所以很重要 这个表示是 信息丰富且明确。 __str__(self)由str()内置函数调用,由print函数调用 语句来计算“非正式的” 对象的字符串表示形式。 这与__repr__()不同 它不必是一个有效的Python 表达:比较方便还是 可以使用简洁的表示 代替。返回值必须为a 字符串对象。
如果你想在一个复杂的数据结构中看到所有的值,那么可以这样做:
from pprint import pprint
pprint(my_var)
其中my_var是您感兴趣的变量。当我使用pprint(vars(my_var))时,我什么都没有得到,这里的其他答案没有帮助,或者方法看起来不必要的长。顺便说一下,在我的特殊情况下,我正在检查的代码有一个字典的字典。
值得指出的是,对于一些自定义类,您可能只会得到一个无用的<someobject。0x7f739267f400>类型的输出。在这种情况下,你可能不得不实现一个__str__方法,或尝试一些其他的解决方案。
我还发现,在我获得这种对象类型输出的一个实例中,vars()显示了我想要的结果。因此,覆盖这两种情况的更好解决方案是分别尝试两种情况。但是使用vars()有时会抛出异常,例如,TypeError: vars()参数必须具有__dict__属性。
我仍然希望找到一些简单的,在所有场景下都可以工作的东西,而不需要第三方库。