“thread._local”对象没有属性

DoN*_*rkO 7 python logging multithreading thread-exceptions

我试图通过添加上下文过滤器来更改日志记录格式。我的格式是这样的

FORMAT = "%(asctime)s %(VAL)s %(message)s"
Run Code Online (Sandbox Code Playgroud)

这是我用来在格式中设置 VAL 的类。

class TEST:
  def __init__(self, val):
    self.test_var=threading.local()
    self.test_var.value=val
  def filter(self,record):
    record.VAL=self.test_var.value
    return True
  def setValue(self,val)
    self.test_var.value=CMDID
Run Code Online (Sandbox Code Playgroud)

它在单线程环境中工作正常,但对于某些多线程环境,我收到错误

<Fault 1: "exceptions.AttributeError:'thread._local' object has no attribute 'value'">
Run Code Online (Sandbox Code Playgroud)

谁能告诉我这里有什么问题??以及如何纠正?

twa*_*erg 5

好吧,例外是告诉您thread._local从返回的对象threading.local()没有value您可以分配的属性val。您可以通过dir(self.test_var)在该self.test_var=threading.local()行后添加 a 来确认。这为我返回:

['__class__', '__delattr__', '__dict__', '__doc__', '__getattribute__', '__hash__',
 '__init__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__',
 '__str__']
Run Code Online (Sandbox Code Playgroud)

事实上,help(threading.local())将向您展示确实存在的方法和属性 -value不在其中。

如果您尝试添加新属性,那么您可能需要:

self.test_var.__setattr__('value',val)
Run Code Online (Sandbox Code Playgroud)

这实际上将创建属性并为其分配值。

实例属性通常不是简单地通过赋值来创建的,就像非实例变量一样......