Как напечатать аргументы переменных с именами из предыдущего стека?
Я хотел бы определить функцию журнала, которая вызывается с сообщением, за которым следует одна или несколько переменных для распечатки. Итак, что-то вроде следующего:
log( "Oh no, error.", x, d)
log будет определяться как:
def log( msg, *arg):
# Loop through arg, printing caller's variable's name and value.
Это будет записывать в файл следующее:
Oh no, error.
x = 5
d = { foo: "Foo", goo: "Goo" }
Можно ли это сделать вообще? Я могу напечатать локальные данные и аргументы, используя inspect, но я не знаю, смогу ли я перебрать значения в текущем кадре, используя имена переменных предыдущего кадра. (locals
в inspect.getargvalues(previousFrame)
есть имена, но и много других имен.)
2 ответа
Я думаю, что вы можете использовать что-то вроде этого:
определение
def log(msg, **kwargs):
print(msg)
for key, value in kwargs.items():
print('{0} = {1}'.format(key,value))
определение (если заказ является обязательным)
def log(msg, **kwargs):
print(msg)
for key, value in sorted(kwargs.items()):
print('{0} = {1}'.format(key,value))
использование
msg='Oh no, error'
log(msg, x=5, y=6)
выход
Oh no, error
y = 6
x = 5
Это может быть очень грязно и может не работать время от времени (это работает на моей машине), но, похоже, делает свое дело.
Более того, не нужно все это **keargs
трюки. Вы просто позвоните log('Message',as,many,args,as,you,want)
и это все.
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'
Даже если log
запускается из другой функции, все в порядке.