鍍金池/ 問(wèn)答/Java  Python  C++  HTML/ 我該怎么把這個(gè)ID參數(shù)去除掉?

我該怎么把這個(gè)ID參數(shù)去除掉?

經(jīng)過(guò)評(píng)論的提醒,問(wèn)題已經(jīng)解決了!通過(guò)traceback信息完美解決。請(qǐng)直接看最下面的代碼:)

在測(cè)試程序的過(guò)程中,由于數(shù)據(jù)很多,經(jīng)常打印一個(gè)變量值會(huì)輸出很多信息;而我通常只需要簡(jiǎn)單看一下變量的值是什么就好了(沒(méi)有用IDE),所以萌生了寫(xiě)個(gè)打印函數(shù),函數(shù)限制變量打印N次。功能我已經(jīng)寫(xiě)好了,其實(shí)很簡(jiǎn)單,代碼在下面貼出來(lái)了。函數(shù)print_times現(xiàn)在有三個(gè)參數(shù):(id,data,times),我想提問(wèn)的是,這個(gè)id參數(shù)我怎么能去除掉?
簡(jiǎn)述一下函數(shù)的實(shí)現(xiàn)過(guò)程以及我為什么想去掉id參數(shù):
首先函數(shù)可能在多個(gè)地方調(diào)用,在類(lèi)里面添加字典print_task來(lái)保存打印任務(wù),print_task={id1:current_times,id2:current_times,...}id用來(lái)在下次被調(diào)用時(shí)關(guān)聯(lián)到打印了多少次。我覺(jué)得這個(gè)id參數(shù)完全就是為了這個(gè)函數(shù)而多余添加的,每次調(diào)用都要先寫(xiě)個(gè)無(wú)關(guān)的參數(shù):print_times('sfsf',data,10)。為了實(shí)現(xiàn)print_times(data,10)這樣簡(jiǎn)潔的寫(xiě)法,有什么辦法可以把id去掉嗎?還是我的實(shí)現(xiàn)方式有問(wèn)題?歡迎探討:)我覺(jué)得本質(zhì)上是:函數(shù)多次調(diào)用狀態(tài)如何相關(guān)聯(lián)的問(wèn)題。
我用的是Python3,提問(wèn)標(biāo)簽有其他語(yǔ)言,是因?yàn)槲矣X(jué)得這是一個(gè)編程問(wèn)題,跟語(yǔ)言無(wú)關(guān),也想看看其他語(yǔ)言實(shí)現(xiàn)有什么不同。
希望對(duì)你有幫助:)

#這是原來(lái)的代碼
class Tclass(object):

    def print_times(self,id,data,times=10,start=1):
        if not hasattr(self,'print_task'):
            self.print_task={}
        current_times=0
        if id in self.print_task.keys():
            current_times=self.print_task[id]
        if current_times<times:
            print(data)
            current_times+=1
            self.print_task[id]=current_times
        else:
            pass
            
t=Tclass()
for i in range(0,10):
    t.print_times('fsfs','hello',5)
#解決代碼~
import traceback
import datetime

class Tclass(object):

    #這里暫時(shí)未做異常檢測(cè) 留到以后報(bào)錯(cuò)再改吧 暫時(shí)對(duì)traceback機(jī)制還不是很了解
    def print_times(self,data,times=10,start=1):

        stack_info=traceback.format_stack(limit=2)[0].split(',')
        #traceback.format_stack(limit=2)輸出如下:
        #['  File "print_times_TEST.py", line 32, in <module>\n    t.print_times(\'fsfs\',\'hello\',5)\n', '  File "print_times_TEST.py", line 15, in print_times\n    stack_info=traceback.format_stack(limit=2)\n']
        #把文件名+行號(hào)作為id
        id=(stack_info[0]+stack_info[1]).strip()
        if not hasattr(self,'print_task'):
            self.print_task={}
        current_times=0
        if id in self.print_task.keys():
            current_times=self.print_task[id]
        if current_times<times:
            print(data)
            current_times+=1
            self.print_task[id]=current_times
        else:
            pass
   
              
t=Tclass()
for i in range(0,10):
    t.print_times('hello',5)
print('*' * 20)   
for i in range(0,10):
    t.print_times('hello traceback',5)
    
print(t.print_task)
print('完美!'*6)
輸出:
C:\Users\src>python print_times_TEST.py
hello
hello
hello
hello
hello
********************
hello traceback
hello traceback
hello traceback
hello traceback
hello traceback
{'File "print_times_TEST.py" line 27': 5, 'File "print_times_TEST.py" line 30': 5}
完美!完美!完美!完美!完美!完美!
回答
編輯回答
安淺陌

我是寫(xiě) Java 的,那么如果要用不那么 OO 的方式(我們一般喜歡用日志 slf4j 之類(lèi)的),那么我會(huì)用下面兩種思路:

public static void printTimes(Object obj, int times) {
    String content = obj.toString();
    // 通過(guò)新建一個(gè)異常來(lái)獲取調(diào)用棧信息,不拋出即可。
    String where = new Exception().getStackTrace()[1].getClassName();
    // 后續(xù)省略
}

public interface Printer {

    // 此法需要 Java 8
    // 聲明默認(rèn)方法,想要為某個(gè)類(lèi)加上按次數(shù)打印功能時(shí)就 implements Printer
    default void printTimes(Object obj, int times) {
        String where = this.getClass().getSimpleName();
        // 后續(xù)省略
    }

}

事實(shí)上新建異常來(lái)獲取調(diào)用棧信息可以拿到非常完整的執(zhí)行環(huán)境信息:

所處類(lèi) | 所處方法 | 所在文件名稱 | 所在文件行數(shù)

歡迎討論。

2017年9月6日 22:51