I would like to define a log function that is called with a message followed by one or more variables to be printed out. So, something like the following:
log( "Oh no, error.", x, d)
log would be defined sorta like:
def log( msg, *arg):
# Loop through arg, printing caller's variable's name and value.
This would log to a file the following:
Oh no, error.
x = 5
d = { foo: "Foo", goo: "Goo" }
Can this be done at all? I can print locals and arguments using inspect, but I don't know if I can iterate through values in the current frame, using the variable names of a previous frame. (locals
in inspect.getargvalues(previousFrame)
has the names, but lots of other names too.)
You can use *args as a non-keyword argument. You will then be able to pass any number of arguments. As you can see, Python will unpack the arguments as a single tuple with all the arguments.
Variable-length arguments, varargs for short, are arguments that can take an unspecified amount of input. When these are used, the programmer does not need to wrap the data in a list or an alternative sequence. In Python, varargs are defined using the *args syntax.
You may need to process a function for more arguments than you specified while defining the function. These arguments are called variable-length arguments and are not named in the function definition, unlike required and default arguments.
I think you can use something like this:
definition
def log(msg, **kwargs):
print(msg)
for key, value in kwargs.items():
print('{0} = {1}'.format(key,value))
definition (if order is a must)
def log(msg, **kwargs):
print(msg)
for key, value in sorted(kwargs.items()):
print('{0} = {1}'.format(key,value))
usage
msg='Oh no, error'
log(msg, x=5, y=6)
output
Oh no, error
y = 6
x = 5
That could be very dirty and may not work from time to time (it does so on my machine), but it seems to do the trick.
Moreover, it doesn't need all these **keargs
tricks. You just call log('Message',as,many,args,as,you,want)
and that's all.
import inspect, gc
def log(msg,*args):
#This gets the source code line that has to do with args
#I mean, that calls log
code=''.join(inspect.getframeinfo(gc.get_referrers(args)[0].f_back).code_context).strip()
#get the arguments (except msg)
c=code.split('log')[1].strip()
c=c.replace('(','').replace(')','')
c=c.split(',')[1:]
if c[-1].endswith(';'):
c[-1]=c[-1].replace(';','')
for x in xrange(0,len(c)):
print c[x],'=',args[x]
a=5; b='hello'
print 'test'
log('hello',a,b);
print 'hello'
Even if log
is run from another function, it's OK.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With