2015-09-15 64 views
7

我想定義一個日誌函數,用一條消息跟一個或多個變量打印出來。因此,類似如下:如何用前一個堆棧的名稱打印變量參數?

log("Oh no, error.", x, d) 

日誌將被八九不離十定義如下:

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來打印局部和參數,但我不知道是否可以使用前一幀的變量名稱來遍歷當前幀中的值。 (localsinspect.getargvalues(previousFrame)有名字,但是很多其他的名字了。)

+1

你如何唯一確定變量名?如果調用者在命名空間中擁有'y'並且它的值也碰巧是'5'會怎麼樣?如果調用者傳遞類似'd ['foo']'的東西呢?你是否需要任意深入地調用調用者命名空間中的對象?如果他們傳遞函數調用的結果呢? 'log('message',x.bar())'?有很多情況很難在這裏解決......儘管你可能會檢查堆棧並打印調用者的局部變量。 – mgilson

+0

*嘆*是的,我想你是正確的mgilson。所以我該怎麼做?我必須刪除這篇文章嗎?或者,也許這是我的一廂情願,我只想要一個記錄我給它的變量的日誌函數。這根本無法完成?所以,如果他們傳遞它5,它會打印5 = 5。如果他們傳遞了y,它會打印y = 5。如果他們傳遞一個對象,它會打印object = str(object)。 – Bitdiot

+0

@Bitdiot,爲什麼?這不是寫得不好或組織糟糕。對我個人而言,這個問題很有趣 – ForceBru

回答

4

我認爲你可以使用這樣的事情:

定義

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 
+2

這很好,因爲它不使用任何黑魔法。另外[顯式優於隱式](https://www.python.org/dev/peps/pep-0020/)。 –

+2

請注意,參數的順序不一定是你所期望的... http://stackoverflow.com/questions/8977594/in-python-what-determines-the-order-while-iterating-through-kwargs –

+0

你是對的,我在這裏沒有把訂單考慮在內,我應該指出字典無序的事實。我編輯了答案。 – jlnabais

1

這可能是非常骯髒,不時可能無法正常工作(它使我的機器上),但似乎這樣的伎倆。

此外,它並不需要所有這些**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從另一個函數運行,它的確定。

+0

我試過了。看起來非常漂亮的代碼,但如果日誌結束了多行,它似乎會絆倒。我仍然喜歡它,但我認爲我傾向於key = val解決方案。 – Bitdiot