首页 > 解决方案 > python:object.__dict__没有显示所有属性

问题描述

我正在尝试打印一个对象的所有属性。目的主要是为了调试。

我正在使用以下代码:

import json
print(json.dumps(object.__dict__), indent=4, sort_keys=True, default=str))

它打印对象的属性。

但我正在使用检查对象的所有属性列表

dir(object)

我发现它__dict__根本没有显示由dir().

我想过使用 dir(object) 但它只是一个没有属性的属性列表。

所以我认为:

`__dict__` has `incomplete` properties but with attirbutes

`dir()` has complete list of properties but no attibutes

那么,获取对象属性的完整字典的最佳方法是什么,以便我可以漂亮地打印并查看使用json.dumps

例子

我在一个 django 项目中工作。这与数据库连接有关

所以这个例子是一个变量名db_con,它是以下对象

<django.db.backends.postgresql.base.DatabaseWrapper object at 0x7f29dee47a58>

__dict__方法

import json
print(json.dumps(db_con.__dict__), indent=4, sort_keys=True, default=str))

输出是

{
    "_thread_ident": ATTRIBUTE_VALUE
    "_thread_sharing_count": ATTRIBUTE_VALUE
    "_thread_sharing_lock": ATTRIBUTE_VALUE
    "alias": ATTRIBUTE_VALUE
    "autocommit": ATTRIBUTE_VALUE
    "client": ATTRIBUTE_VALUE
    "close_at": ATTRIBUTE_VALUE
    "closed_in_transaction": ATTRIBUTE_VALUE
    "commit_on_exit": ATTRIBUTE_VALUE
    "connection": ATTRIBUTE_VALUE
    "creation": ATTRIBUTE_VALUE
    "errors_occurred": ATTRIBUTE_VALUE
    "execute_wrappers": ATTRIBUTE_VALUE
    "features": ATTRIBUTE_VALUE
    "force_debug_cursor": ATTRIBUTE_VALUE
    "in_atomic_block": ATTRIBUTE_VALUE
    "introspection": ATTRIBUTE_VALUE
    "isolation_level": ATTRIBUTE_VALUE
    "needs_rollback": ATTRIBUTE_VALUE
    "ops": ATTRIBUTE_VALUE
    "queries_log": ATTRIBUTE_VALUE
    "run_commit_hooks_on_set_autocommit_on": ATTRIBUTE_VALUE
    "run_on_commit": ATTRIBUTE_VALUE
    "savepoint_ids": ATTRIBUTE_VALUE
    "savepoint_state": ATTRIBUTE_VALUE
    "settings_dict": ATTRIBUTE_VALUE
        "ATOMIC_REQUESTS": ATTRIBUTE_VALUE
        "AUTOCOMMIT": ATTRIBUTE_VALUE
        "CONN_MAX_AGE": ATTRIBUTE_VALUE
        "ENGINE": ATTRIBUTE_VALUE
        "HOST": ATTRIBUTE_VALUE
        "NAME": ATTRIBUTE_VALUE
        "OPTIONS": ATTRIBUTE_VALUE
        "PASSWORD": ATTRIBUTE_VALUE
        "PORT": ATTRIBUTE_VALUE
        "TEST": ATTRIBUTE_VALUE
            "CHARSET": ATTRIBUTE_VALUE
            "COLLATION": ATTRIBUTE_VALUE
            "MIRROR": ATTRIBUTE_VALUE
            "NAME": ATTRIBUTE_VALUE
        },
        "TIME_ZONE": ATTRIBUTE_VALUE
        "USER": ATTRIBUTE_VALUE
    },
    "timezone": ATTRIBUTE_VALUE
    "timezone_name": ATTRIBUTE_VALUE
    "validation": ATTRIBUTE_VALUE
    "wrap_database_errors": ATTRIBUTE_VALUE

以及使用 dir() 的属性

print(json.dumps(dir(db_con), indent=4, sort_keys=True, default=str))
[
    "Database",
    "SchemaEditorClass",
    "__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__",
    "__str__",
    "__subclasshook__",
    "__weakref__",
    "_close",
    "_commit",
    "_cursor",
    "_named_cursor_idx",
    "_nodb_connection",
    "_prepare_cursor",
    "_rollback",
    "_savepoint",
    "_savepoint_allowed",
    "_savepoint_commit",
    "_savepoint_rollback",
    "_set_autocommit",
    "_thread_ident",
    "_thread_sharing_count",
    "_thread_sharing_lock",
    "alias",
    "allow_thread_sharing",
    "autocommit",
    "check_constraints",
    "check_settings",
    "chunked_cursor",
    "clean_savepoints",
    "client",
    "client_class",
    "close",
    "close_at",
    "close_if_unusable_or_obsolete",
    "closed_in_transaction",
    "commit",
    "commit_on_exit",
    "connect",
    "connection",
    "constraint_checks_disabled",
    "copy",
    "create_cursor",
    "creation",
    "creation_class",
    "cursor",
    "data_type_check_constraints",
    "data_types",
    "data_types_suffix",
    "dec_thread_sharing",
    "disable_constraint_checking",
    "display_name",
    "enable_constraint_checking",
    "ensure_connection",
    "ensure_timezone",
    "errors_occurred",
    "execute_wrapper",
    "execute_wrappers",
    "features",
    "features_class",
    "force_debug_cursor",
    "get_autocommit",
    "get_connection_params",
    "get_new_connection",
    "get_rollback",
    "in_atomic_block",
    "inc_thread_sharing",
    "init_connection_state",
    "introspection",
    "introspection_class",
    "is_usable",
    "isolation_level",
    "make_cursor",
    "make_debug_cursor",
    "needs_rollback",
    "on_commit",
    "operators",
    "ops",
    "ops_class",
    "pattern_esc",
    "pattern_ops",
    "pg_version",
    "prepare_database",
    "queries",
    "queries_limit",
    "queries_log",
    "queries_logged",
    "rollback",
    "run_and_clear_commit_hooks",
    "run_commit_hooks_on_set_autocommit_on",
    "run_on_commit",
    "savepoint",
    "savepoint_commit",
    "savepoint_ids",
    "savepoint_rollback",
    "savepoint_state",
    "schema_editor",
    "set_autocommit",
    "set_rollback",
    "settings_dict",
    "temporary_connection",
    "timezone",
    "timezone_name",
    "validate_no_atomic_block",
    "validate_no_broken_transaction",
    "validate_thread_sharing",
    "validation",
    "validation_class",
    "vendor",
    "wrap_database_errors"
]

我想用来db_con['queries']获取查询列表,但它没有显示在中__dict__,如果我不知道db_con['queries']存在,可能会令人困惑dir()

我发现的第三方解决方案:

我正在使用 runserver_plus

python manage.py runserver_plus

Runserver_plus:Django-extensions 包含一个管理命令 (runserver_plus) 来启动 Werkzeug 交互式调试器与您的项目

Werkzeug:Werkzeug 是一个用于 Python 的 WSGI 实用程序库。除了其他之外,它还包括一个交互式调试器——这意味着当你的 python 应用程序抛出异常时,Werkzeug 将在浏览器中显示异常堆栈跟踪(这没什么大不了的),并允许你在任何你想要的地方交互式地编写 python 命令那个堆栈跟踪(这是重要的东西)。

无论我想检查我a=+1之后添加的变量,以便它引发异常,(UnboundLocalError: local variable 'a' referenced before assignment)然后我可以在那里打开一个交互式控制台并检查使用 dump(var)它显示所有属性的对象属性。目前我使用它检查属性。

我想用普通的python方式来做。

标签: pythonjsondjangopretty-print

解决方案


obj.__dict__是实例属性的存储(对于基于 dict 的类 - 有些是基于插槽的,有些(C 编码)只是,好吧,它们是 xD)。其他“属性”(警告:在 Python 中,“属性”也是为计算属性提供通用支持的内置类的名称),您会发现dir(obj)它们属于该类或其父类之一,因此它们显然是不在obj.__dict__

此外,FWIWdir()不一定列出对象的所有属性:

模块builtin中内置函数 dir 的帮助:

dir(...) dir([object]) -> 字符串列表

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.

如果您真的想检索所有属性,可以使用[getattr][1](obj, name[, default])ie:

everything = {k: getattr(obj, k) for k in dir(obj)}

但是您将无法将其序列化为 json - 函数/方法、属性(Python 内置类型...)、类(对象的类)和许多其他东西不是 json 可序列化的(您将如何序列化一个函数?)

此外,您可能有实现类__getattr__(通常用于动态委托),因此即使dir有可能在您的对象上可访问但无法通过检查列出的属性(在一般意义上)。

那么获取对象属性的完整字典的最佳方法是什么,以便我可以漂亮地打印

类似的东西inspect.getmembers(obj)浮现在脑海。但是您可能会发现这obj.__dict__通常已经是最有用的部分。

并查看使用 json.dumps

嗯,参照上面...

我想使用 db_con['queries'] 来获取查询列表,但它没有显示在dict中,如果不知道我通过 dir() 知道的 db_con['queries'] 存在,可能会造成混淆

如果你在 python shell 中,你可以使用内置的帮助系统


推荐阅读