I am trying to print all the attibutes of an object. The purpose is mainly for debugging.
I am using the following code:
import json
print(json.dumps(object.__dict__), indent=4, sort_keys=True, default=str))
It prints the attibutes of the object.
But i was checking the list of all properties of the object using
dir(object)
I found that __dict__
does not show some properties at all which are listed by dir()
.
I thought of using dir(object) but it only a list of properties without attributes.
So i think:
`__dict__` has `incomplete` properties but with attirbutes
`dir()` has complete list of properties but no attibutes
So what is the best way to get a full dictionary of a attibutes of an object so that i can pretty print and see using json.dumps
EXAMPLE
I am working in a django project. And this is with related to db connection
so the example is of a variable names db_con
which is of the following object
<django.db.backends.postgresql.base.DatabaseWrapper object at 0x7f29dee47a58>
__dict__
way
import json
print(json.dumps(db_con.__dict__), indent=4, sort_keys=True, default=str))
The output is
{
"_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
And the attibutes using 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"
]
I want to use db_con['queries']
to get a the list of queries but its not shown in __dict__
and can be confusing if dont know db_con['queries']
exists which i came to know through dir()
Thirdparty Solution i found:
I am using runserver_plus
python manage.py runserver_plus
Runserver_plus: Django-extensions includes a management command (runserver_plus) to start the Werkzeug interactive debugger with your project
Werkzeug: Werkzeug is a WSGI utility library for Python. Beyond others, it includes an interactive debugger - what this means is that when your python application throws an exception, Werkzeug will display the exception stacktrace in the browser (that’s not a big deal) and allow you to write python commands interactively wherever you want in that stacktrace (that’s the important stuff).
whereever i want to check a variable i add a=+1
after that so that it throws an exception (UnboundLocalError: local variable 'a' referenced before assignment)
then i can open an interactive console there and check the object attibutes using dump(var)
which shows all the attributes. Currently i check the attributes using that.
I want to do it using regular python way.
obj.__dict__
is the storage for instance attributes (for dict-based classes - some are slot-based and some (C coded) are just, well, what they are xD). Other "properties" (caveat: in Python, 'property' is also the name of a builtin class that provides generic support for computed attributes) that you'll find using dir(obj)
belong either to the class or one of it's parent, so they are obviously not in obj.__dict__
.
Also and FWIW, dir()
doesn't necessarily lists all of an object's properties :
Help on built-in function dir in module builtin:
dir(...) dir([object]) -> list of strings
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.
If you really want to retrieve all properties values, you can use [getattr][1](obj, name[, default])
ie:
everything = {k: getattr(obj, k) for k in dir(obj)}
BUT you won't be able to serialize this to json - functions / methods, properties (the Python builtin type...), classes (the object's class) and quite a few other things are not json-serializable (how would you serialize a function ?)
Also, you may have classes implementing __getattr__
(usually for dynamic delegation), so even with dir
there might be properties (in the generic meaning) that are accessible on your object but that just can't be listed via inspection.
So what is the best way to get a full dictionary of a attibutes of an object so that i can pretty print
Something like inspect.getmembers(obj)
comes to mind. But you may find out that obj.__dict__
is usually the most useful part already.
and see using json.dumps
Well, cf above...
I want to use db_con['queries'] to get a the list of queries but its not shown in dict and can be confusing if dont know db_con['queries'] exists which i came to know through dir()
if you're in the python shell, you can just use the builtin help system.