Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Python 2中调用logging.setLogRecordFactory?_Python_Python 3.x_Logging_Python 2.x_Python Logging - Fatal编程技术网

如何在Python 2中调用logging.setLogRecordFactory?

如何在Python 2中调用logging.setLogRecordFactory?,python,python-3.x,logging,python-2.x,python-logging,Python,Python 3.x,Logging,Python 2.x,Python Logging,给出以下简单示例: import logging class SmartLogRecord(logging.LogRecord): """ Dummy LogRecord example """ def getMessage(self): return self.msg % self.args logging.setLogRecordFactory(SmartLogRecord) var = 'SmartLogRecord' logging.warning

给出以下简单示例:

import logging

class SmartLogRecord(logging.LogRecord):
    """ Dummy LogRecord example """

    def getMessage(self):
        return self.msg % self.args

logging.setLogRecordFactory(SmartLogRecord)

var = 'SmartLogRecord'
logging.warning('I am a %s', var)
我可以在
python3
上运行它,并使用我的自定义
LogRecord
类,但是
python2
会抛出一个错误:

linux@linux-PC$ python3 text.py
WARNING:root:I am a SmartLogRecord

linux@linux-PC$ python2 text.py
Traceback (most recent call last):
  File "text.py", line 9, in <module>
    logging.setLogRecordFactory(SmartLogRecord)
AttributeError: 'module' object has no attribute 'setLogRecordFactory'

linux@linux-PC$ python3 --version
Python 3.7.2

linux@linux-PC$ python2 --version
Python 2.7.16
linux@linux-PC$python3 text.py
警告:root:我是SmartLogRecord
linux@linux-PC$python2 text.py
回溯(最近一次呼叫最后一次):
文件“text.py”,第9行,在
logging.setLogRecordFactory(SmartLogRecord)
AttributeError:“模块”对象没有属性“setLogRecordFactory”
linux@linux-PC$python3——版本
Python 3.7.2
linux@linux-PC$python2——版本
Python 2.7.16

以下是CPython 3.7中的
setLogRecordFactory()
,这是它的辉煌:

# https://github.com/python/cpython/blob/29500737d45cbca9604d9ce845fb2acc3f531401/Lib/logging/__init__.py#L386
_logRecordFactory = LogRecord

def setLogRecordFactory(factory):
    global _logRecordFactory
    _logRecordFactory = factory

def getLogRecordFactory():
    return _logRecordFactory

def makeLogRecord(dict):
    rv = _logRecordFactory(None, None, "", 0, "", (), None, None)
    rv.__dict__.update(dict)
    return rv
调用此函数的位置是在
Logger.makeRecord()中调用的:

相反,在Python 2中,这不是一件事:

# https://github.com/python/cpython/blob/7c2c01f02a1821298a62dd16ecc3a12da663e14b/Lib/logging/__init__.py#L1261
def makeRecord(self, name, level, fn, lno, msg, args, exc_info, func=None, extra=None):
    """
    A factory method which can be overridden in subclasses to create
    specialized LogRecords.
    """
    rv = LogRecord(name, level, fn, lno, msg, args, exc_info, func)
您可以做的是基本上替换
记录器
对象上的
.makeRecord()
绑定方法。换言之:

>>> class A:
...     def f(self, a, b):
...         return a + b

>>> def new_f(self, a, b):
...     return a * b
... 
>>> A.f = new_f
>>> A().f(10, 20)
200
这看起来像:

class MyLogRecord(logging.LogRecord):
    pass
    # override stuff here

def makeRecord(self, name, level, fn, lno, msg, args, exc_info, func=None, extra=None):
        print "Using a MyLogRecord instance"
        rv = MyLogRecord(name, level, fn, lno, msg, args, exc_info, func)
        if extra is not None:
            for key in extra:
                if (key in ["message", "asctime"]) or (key in rv.__dict__):
                    raise KeyError("Attempt to overwrite %r in LogRecord" % key)
                rv.__dict__[key] = extra[key]
        return rv

logging.Logger.makeRecord = makeRecord
说明:

>>> logging.error("hello")
Using a MyLogRecord instance
ERROR:root:hello
在本例中,您只是根据使用单个other
MyLogRecord
类的特定需要来定制内容。如果确实需要,您可以编写自己的
setLogRecordFactory()
,如上图所示,然后在替换的
.makeRecord()
方法中使用
\logRecordFactory
,就像Python 3所做的那样


假设/备选方案(子类,不替换) 还有一条评论:这一切都假设您想要影响在别处创建的非“您自己”的
logger
实例。如果您只想影响自己的代码定义的记录器,那么您可以将
Logger
子类化,而不是完全替换属于
日志记录模块命名空间的
Logger

>>> logging.error("hello")
Using a MyLogRecord instance
ERROR:root:hello