首页 > 解决方案 > 当前方法和类名进入日志记录;这些方法在功能上是否等效?

问题描述

在下面基于先前答案的测试脚本中,所有技术都提供了将信息性消息返回到屏幕和日志文件的所需结果。

除了检查方法的执行时间似乎要慢得多之外,我看不到在这些替代方法之间进行选择的任何方法。在一种或另一种技术中是否存在任何隐藏的陷阱?我将在未来移动项目 Python 3,所以最前向兼容的东西会比现在最快的东西更好。

结果:

I am Bob, an instance of B, speaking from f1
I am Bob, an instance of B, speaking from f2
I am Bob, an instance of B, speaking from f3
I am Bob, an instance of B, speaking from f4
I am Bob, an instance of B, speaking from g
I am Bob, an instance of B, speaking from h

脚本:

class A(object):
    def __init__(self):
        self.cname = self.__class__.__name__
        logfmt     = "%(levelname)s - %(message)s"
        logging.basicConfig(filename="logme.log", level=logging.DEBUG, 
                            format=logfmt, filemode='w')
        self.logger = logging.getLogger()

class B(A):
    def __init__(self, name):
        self.name = name
        A.__init__(self)

    def whoami(self):
        return inspect.stack()[1][3]

    def whosdaddy(self):
        return inspect.stack()[2][3]

    def who_i(self, i=None):
        if i==None: i=1
        return inspect.stack()[i][3]

    def mee(self):
        return inspect.stack()[1][3]

    def f1(self):
        msg   = ('I am {}, an instance of {}, speaking from {}'.format(self.name, self.cname, self.mee()))
        print msg
        self.logger.info(msg) 

    def f2(self):    # 2011 https://stackoverflow.com/a/5067654/3904031
        me  = inspect.stack()[0][3]
        msg   = ('I am {}, an instance of {}, speaking from {}'.format(self.name, self.cname, me))
        print msg
        self.logger.info(msg) 

    def f3(self):    # 2015 https://stackoverflow.com/a/33159791/3904031
        msg   = ('I am {}, an instance of {}, speaking from {}'.format(self.name, self.cname, self.whoami()))
        print msg
        self.logger.info(msg) 

    def f4(self):
        msg   = ('I am {}, an instance of {}, speaking from {}'.format(self.name, self.cname, self.who_i(1)))
        print msg
        self.logger.info(msg) 

    def g(self):
        me  = sys._getframe().f_code.co_name    # 2013 https://stackoverflow.com/a/15725912/3904031
        msg   = ('I am {}, an instance of {}, speaking from {}'.format(self.name, self.cname, me))
        print msg
        self.logger.info(msg) 

    def h(self):
        frame = inspect.currentframe()
        me    = inspect.getframeinfo(frame).function    # 2015 https://stackoverflow.com/a/33162432/3904031
        msg   = ('I am {}, an instance of {}, speaking from {}'.format(self.name, self.cname, me))
        print msg
        self.logger.info(msg) 

import sys, inspect, logging

b = B('Bob')

for x in ['f1', 'f2', 'f3', 'f4', 'g', 'h']:
    getattr(b, x)()

标签: pythonpython-3.xpython-2.7

解决方案


事实证明这是一个 x/y 问题。根据这个答案logging,似乎拥有我需要的所有功能 。

通过使用%(funcName)s格式语句中的属性,以下脚本无需查看堆栈即可完成所有操作,包括对控制台的回显。

文档:https ://docs.python.org/3/library/logging.html#logrecord-attributes

I am Bob, an instance of B, speaking from  i

从:

class A(object):
    def __init__(self):

        self.cname = self.__class__.__name__

        logformat  = '%(message)s %(funcName)s '

        logging.basicConfig(filename="logme.log", level=logging.DEBUG, 
                            format=logformat, filemode='w')

        self.logger = logging.getLogger()

        console   = logging.StreamHandler()   # no more print statements, yay!
        formatter = logging.Formatter(logformat)
        console.setFormatter(formatter)

        console.setLevel(logging.DEBUG)

        logging.getLogger('').addHandler(console)

class B(A):
    def __init__(self, name):
        self.name = name
        A.__init__(self)

    def i(self):
        msg   = ('I am {x.name}, an instance of {x.cname}, speaking from '.format(x=self))
        self.logger.info(msg)

import sys, inspect, logging

b = B('Bob')

b.i()

推荐阅读