Dark magics about variable names in python
Overall
score
90%
Primary functions for retrieving variable names from function calls and getting names of variables passed as arguments. These functions form the foundation of varname's capabilities.
Gets the name of the variable(s) that a function call or class instantiation is assigned to from inside the function.
def varname(
frame: int = 1,
ignore: IgnoreType = None,
multi_vars: bool = False,
raise_exc: bool = True,
strict: bool = True
) -> Union[str, Tuple[Union[str, Tuple], ...]]:
"""
Get the name of the variable(s) that assigned by function call or class instantiation.
Args:
frame: Nth frame used to retrieve the variable name. This means N-1
intermediate frames will be skipped. Note that frames matching
ignore will not be counted.
ignore: Frames to be ignored in order to reach the Nth frame. Can be:
- A module (or filename): calls from it and submodules ignored
- A function: direct function calls ignored
- Tuple of (function, int): decorated function with decorator count
- Tuple of (module/filename, qualname): qualified name matching
multi_vars: Whether allow multiple variables on left-hand side. If True,
returns tuple of variable names even for single variable.
raise_exc: Whether to raise exception if failed to retrieve ast node.
Note: does NOT suppress ImproperUseError exceptions.
strict: Whether to only return variable name if result is assigned
directly (e.g. a = func() rather than a = [func()]).
Returns:
Variable name as string, or None if raise_exc=False and retrieval failed.
Tuple or hierarchy of variable names when multi_vars=True.
Raises:
VarnameRetrievingError: When unable to retrieve ast node and raise_exc=True
ImproperUseError: When varname usage is improper (multiple vars with
multi_vars=False, non-direct assignment with strict=True)
MultiTargetAssignmentWarning: When multiple targets in assignment
(e.g. a = b = func())
"""from varname import varname
# Basic usage
def create_object():
return varname()
my_object = create_object() # my_object == 'my_object'
# Multiple variables
def create_pair():
return varname(multi_vars=True)
a, b = create_pair() # ('a', 'b')
# With ignore - skip decorator frames
def logged(func):
def wrapper(*args, **kwargs):
name = varname(ignore=logged) # Skip the decorator frame
print(f"Creating {name}")
return func(*args, **kwargs)
return wrapper
@logged
def make_data():
return [1, 2, 3]
data = make_data() # Prints: Creating dataGets the names of variables passed as arguments to a function, supporting both single and multiple variable inspection.
def nameof(
var: Any,
*more_vars: Any,
frame: int = 1,
vars_only: bool = True
) -> Union[str, Tuple[str, ...]]:
"""
Get the names of the variables passed in.
Args:
var: The variable to retrieve the name of
*more_vars: Other variables to retrieve the names of
frame: Frame where this function is called from wrapper. frame=1 means
no wrappers. Standard library calls are ignored.
vars_only: Whether only allow variables/attributes as arguments or any
expressions. If False, source expressions are returned.
Returns:
Name/source of variable if single argument passed.
Tuple of names/sources if multiple variables passed.
For attributes with vars_only=True, only attribute name returned.
For attributes with vars_only=False, full expression returned.
Raises:
VarnameRetrievingError: When callee's node cannot be retrieved or
trying to retrieve full name of non-attribute calls.
Note:
Works in environments where source code is available. In REPL/exec
environments, falls back to bytecode analysis with limitations:
- Only single variable supported
- No keyword arguments allowed
- No full attribute name support
"""from varname import nameof
# Basic variable name retrieval
a = 1
name = nameof(a) # name == 'a'
# Multiple variables
b = 2
names = nameof(a, b) # names == ('a', 'b')
# Attribute access
class Data:
def __init__(self):
self.value = 42
obj = Data()
attr_name = nameof(obj.value, vars_only=True) # attr_name == 'value'
full_name = nameof(obj.value, vars_only=False) # full_name == 'obj.value'
# In function with frame adjustment
def process_variables(*vars):
return nameof(*vars, frame=2) # Skip one additional frame
def wrapper(*args):
return process_variables(*args)
x, y = 10, 20
result = wrapper(x, y) # result == ('x', 'y')Install with Tessl CLI
npx tessl i tessl/pypi-varnameevals
scenario-1
scenario-2
scenario-3
scenario-4
scenario-5
scenario-6
scenario-7
scenario-8
scenario-9
scenario-10