我该怎么把这个ID参数去除掉?

经过评论的提醒,问题已经解决了!通过traceback信息完美解决。请直接看最下面的代码:)

在测试程序的过程中,由于数据很多,经常打印一个变量值会输出很多信息;而我通常只需要简单看一下变量的值是什么就好了(没有用IDE),所以萌生了写个打印函数,函数限制变量打印N次。功能我已经写好了,其实很简单,代码在下面贴出来了。函数print_times现在有三个参数:(id,data,times),我想提问的是,这个id参数我怎么能去除掉?
简述一下函数的实现过程以及我为什么想去掉id参数:
首先函数可能在多个地方调用,在类里面添加字典print_task来保存打印任务,print_task={id1:current_times,id2:current_times,...}id用来在下次被调用时关联到打印了多少次。我觉得这个id参数完全就是为了这个函数而多余添加的,每次调用都要先写个无关的参数:print_times('sfsf',data,10)。为了实现print_times(data,10)这样简洁的写法,有什么办法可以把id去掉吗?还是我的实现方式有问题?欢迎探讨:)我觉得本质上是:函数多次调用状态如何相关联的问题。
我用的是Python3,提问标签有其他语言,是因为我觉得这是一个编程问题,跟语言无关,也想看看其他语言实现有什么不同。
希望对你有帮助:)

#这是原来的代码
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):

    #这里暂时未做异常检测 留到以后报错再改吧 暂时对traceback机制还不是很了解
    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']
        #把文件名+行号作为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}
完美!完美!完美!完美!完美!完美!
阅读 2.2k
1 个回答

我是写 Java 的,那么如果要用不那么 OO 的方式(我们一般喜欢用日志 slf4j 之类的),那么我会用下面两种思路:

public static void printTimes(Object obj, int times) {
    String content = obj.toString();
    // 通过新建一个异常来获取调用栈信息,不抛出即可。
    String where = new Exception().getStackTrace()[1].getClassName();
    // 后续省略
}

public interface Printer {

    // 此法需要 Java 8
    // 声明默认方法,想要为某个类加上按次数打印功能时就 implements Printer
    default void printTimes(Object obj, int times) {
        String where = this.getClass().getSimpleName();
        // 后续省略
    }

}

事实上新建异常来获取调用栈信息可以拿到非常完整的执行环境信息:

所处类 | 所处方法 | 所在文件名称 | 所在文件行数

欢迎讨论。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题