Retrieving variable names of function or class calls.
Project description
Dark magics about variable names in python
Installation
pip install python-varname
Features
- Fetching variable names from inside the function/class call using
varname
- Fetching variable names directly using
nameof
- A value wrapper to store the variable name that a value is assigned to using
Wrapper
- Detecting next immediate attribute name using
will
- Shortcut for
collections.namedtuple
- Injecting
__varname__
to objects
Credits
Thanks goes to these awesome people/projects:
@alexmojaki |
executing |
Usage
Retrieving the variable names from inside a function call/class instantiation
-
From insdie a function call
from varname import varname def function(): return varname() func = function() # func == 'func'
-
varname
calls being buried deeplydef function(): # I know that at which stack this will be called return varname(caller=3) def function1(): return function() def function2(): return function1() func = function2() # func == 'func'
-
Retrieving instance name of a class
class Klass: def __init__(self): self.id = varname() def copy(self): # also able to fetch inside a member call return varname() k = Klass() # k.id == 'k' k2 = k.copy() # k2 == 'k2'
-
Some unusual use
func = [function()] # func == ['func'] func = [function(), function()] # func == ['func', 'func'] func = function(), function() # func = ('func', 'func') func = func1 = function() # func == func1 == 'func' # a warning will be printed # since you may not want func1 to be 'func' x = func(y = func()) # x == 'x' # get part of the name func_abc = function()[-3:] # func_abc == 'abc' # function alias supported now function2 = function func = function2() # func == 'func' a = lambda: 0 a.b = function() # a.b == 'b' # Since v0.1.3 # We can ask varname to raise exceptions # if it fails to detect the variable name def get_name(raise_exc): return varname(raise_exc=raise_exc) a = {} a['b'] = get_name(True) # VarnameRetrievingError a['b'] = get_name(False) # None
Value wrapper
from varname import Wrapper
foo = Wrapper(True)
# foo.name == 'foo'
# foo.value == True
bar = Wrapper(False)
# bar.name == 'bar'
# bar.value == False
def values_to_dict(*args):
return {val.name: val.value for val in args}
mydict = values_to_dict(foo, bar)
# {'foo': True, 'bar': False}
Getting variable names directly
from varname import varname, nameof
a = 1
aname = nameof(a)
# aname == 'a
b = 2
aname, bname = nameof(a, b)
# aname == 'a', bname == 'b'
def func():
return varname() + '_suffix'
f = func()
# f == 'f_suffix'
fname = nameof(f)
# fname == 'f'
Detecting next immediate attribute name
from varname import will
class AwesomeClass:
def __init__(self):
self.will = None
def permit(self):
self.will = will(raise_exc=False)
if self.will == 'do':
# let self handle do
return self
raise AttributeError('Should do something with AwesomeClass object')
def do(self):
if self.will != 'do':
raise AttributeError("You don't have permission to do")
return 'I am doing!'
awesome = AwesomeClass()
awesome.do() # AttributeError: You don't have permission to do
awesome.permit() # AttributeError: Should do something with AwesomeClass object
awesome.permit().do() == 'I am doing!'
Shortcut for collections.namedtuple
# instead of
from collections import namedtuple
Name = namedtuple('Name', ['first', 'last'])
# we can do:
from varname import namedtuple
Name = namedtuple(['first', 'last'])
Injecting __varname__
from varname import inject
class MyList(list):
pass
a = inject(MyList())
b = inject(MyList())
a.__varname__ == 'a'
b.__varname__ == 'b'
a == b
# other methods not affected
a.append(1)
b.append(1)
a == b
Reliability and limitations
python-varname
is all depending on executing
package to look for the node.
The node executing
detects is ensured to be the correct one (see this).
It partially works with environments where other AST magics apply, including
pytest
, ipython
, macropy
, birdseye
, reticulate
with R
, etc. Neither
executing
nor python-varname
is 100% working with those environments. Use
it at your own risk.
For example:
-
This will not work with
pytest
:a = 1 assert nameof(a) == 'a' # do this instead name_a = nameof(a) assert name_a == 'a'
-
R
withreticulate
.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.