我正在调试我的调试模块,我依靠 try ... catch 来检测 TypeError 并正确格式化我的消息,然后,我注意到当传递字典时,Python 不会引发传统的异常。
>>> 'var' % {1: 'variable'}
'var'
>>> 'var' % (1,)
Traceback (most recent call last):
File "<string>", line 1, in <module>
这是日志模块的最小示例:
import logging
class SmartLogRecord(logging.LogRecord):
def _getMessage(self, remaining_arguments):
try:
if self.args:
remaining_arguments.append( self.msg % self.args )
else:
remaining_arguments.append( self.msg )
return False
except TypeError as error:
last = self.args[-1]
self.args = self.args[:-1]
remaining_arguments.append( str( last ) )
if len( self.args ):
return True
else:
remaining_arguments.append( self.msg )
return False
def getMessage(self):
"""
Return the message for this LogRecord.
Return the message for this LogRecord after merging any user-supplied
arguments with the message.
"""
remaining_arguments = []
self.msg = str( self.msg )
while self._getMessage( remaining_arguments ): pass
return " ".join( reversed( remaining_arguments ) )
logging.setLogRecordFactory(SmartLogRecord)
var = 'SmartLogRecord'
logging.warning('I am a', var)
dumb = {1: 'variable'}
logging.warning('I am a', dumb)
运行它你得到:
WARNING:root:I am a SmartLogRecord
WARNING:root:I am a
如您所见,最后dumb
一条消息丢失了。
我认为观察到的行为符合docs。
如果 format 需要单个参数,则值可能是单个非元组对象。[5] 否则,values 必须是一个元组,它的项数正好是格式字符串指定的项数,或者是单个映射对象(例如,字典)。
注[5]:
因此,要仅格式化元组,您应该提供一个单例元组,其唯一元素是要格式化的元组。
这解释了只有在完全匹配格式字符串要求时才接受元组。包含一项本身不是元组的元组不可能匹配任何格式字符串并且总是引发异常。
它还解释了 dict 总是被接受为一种类型,但可能会产生其他错误。
就我错的情况而言,有一种包罗万象的可能性,即您刚刚发现了另一个“怪癖”。他们明确警告:
此处描述的格式化操作表现出各种怪癖,这些怪癖会导致许多常见错误(例如无法正确显示元组和字典)。使用较新的格式化字符串文字或 str.format() 接口有助于避免这些错误。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句