这里我要找的是PHP的print_r函数。

这样我就可以通过查看有问题的对象的状态来调试脚本。


当前回答

如果你想在一个复杂的数据结构中看到所有的值,那么可以这样做:

from pprint import pprint
pprint(my_var)

其中my_var是您感兴趣的变量。当我使用pprint(vars(my_var))时,我什么都没有得到,这里的其他答案没有帮助,或者方法看起来不必要的长。顺便说一下,在我的特殊情况下,我正在检查的代码有一个字典的字典。

值得指出的是,对于一些自定义类,您可能只会得到一个无用的<someobject。0x7f739267f400>类型的输出。在这种情况下,你可能不得不实现一个__str__方法,或尝试一些其他的解决方案。

我还发现,在我获得这种对象类型输出的一个实例中,vars()显示了我想要的结果。因此,覆盖这两种情况的更好解决方案是分别尝试两种情况。但是使用vars()有时会抛出异常,例如,TypeError: vars()参数必须具有__dict__属性。

我仍然希望找到一些简单的,在所有场景下都可以工作的东西,而不需要第三方库。

其他回答

我没有测试过性能,但我相信这是在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),它将枚举对象的所有方法和属性,如果您只需要它的属性,则会对性能造成影响。

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))

从答案中,可以稍微修改一下,只得到一个对象的“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))

在临时添加此函数时非常有用,并且可以在不修改现有源代码的情况下删除此函数

也许值得一查——

Python中是否存在与Perl的Data:: dump相同的程序?

我的建议是——

https://gist.github.com/1071857

注意,perl有一个名为Data::Dumper的模块,它将对象数据转换回perl源代码(注意:它不将代码转换回源代码,而且几乎总是你不想在输出中使用对象方法函数)。这可以用于持久性,但常见的目的是用于调试。

标准的python pprint有很多事情无法实现,特别是当它看到一个对象的实例时,它只是停止下降,并给你对象的内部十六进制指针(errr,顺便说一下,这个指针并没有很多用处)。所以简而言之,python就是这个伟大的面向对象范式,但是你从盒子里拿出来的工具是为处理对象以外的东西而设计的。

perl Data::Dumper允许你控制你想要去的深度,还可以检测循环链接结构(这真的很重要)。这个过程在perl中更容易实现,因为对象除了它们的祝福之外没有任何特殊的魔力(一个普遍定义良好的过程)。

这个项目修改pprint以显示所有对象字段值,它忽略对象__repr__成员函数,它还递归到嵌套对象。它与python3一起工作,参见https://github.com/MoserMichael/pprintex 你可以通过pip: pip install printex安装它