Skip to content

Instantly share code, notes, and snippets.

@MarcinKonowalczyk
Last active January 4, 2023 15:11
Show Gist options
  • Save MarcinKonowalczyk/f1ce16a7958ab6d14578664304cb66d8 to your computer and use it in GitHub Desktop.
Save MarcinKonowalczyk/f1ce16a7958ab6d14578664304cb66d8 to your computer and use it in GitHub Desktop.
import inspect
from operator import itemgetter
def var_name(var, *, ignore_underscore: bool = True, fix: bool = True):
""" Find all the variable names in caller's parent scope whos value is 'var'
Example
-------
>>> def meta_printer(var):
... print(f"{var_name(var)} = {var}")
>>> params = dict(hello=1, sailor=True)
>>> meta_printer(params)
params = {'hello': 1, 'sailor': True}
>>> meta_printer('hello')
var = hello
"""
callers_parent_scope = inspect.currentframe().f_back.f_back.f_locals.items()
filter_ = lambda e: e[1] is var and not (ignore_underscore and e[0].startswith("_"))
names_from_scope = lambda scope: list(map(itemgetter(0), filter(filter_, scope)))
names = names_from_scope(callers_parent_scope)
# If more than one name is found and 'fix' is enabled, attempt to fix with
# the name of variable passed to *this* function (as opposed to the caller).
if fix:
if len(names) != 1:
parent_scope = inspect.currentframe().f_back.f_locals.items()
names = names_from_scope(parent_scope)
names = [""] if len(names) != 1 else names # Fall back to empty string
names = names[0]
return names
def meta_printer(var: Any):
""" Prints the name and value of the variable"""
print(f"{var_name(var)} = {var}")
if __name__ == "__main__":
params = dict(hello=1, sailor=True)
meta_printer(params)
meta_printer('hello')
# This is already a feature in Python 3.8
# https://docs.python.org/3/whatsnew/3.8.html#f-strings-support-for-self-documenting-expressions-and-debugging
import sys
if sys.version_info > (3, 8):
print(f"{params = }")
print(f"{'hello' = }")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment