El objeto ‘thread._local’ no tiene atributo

Estaba intentando cambiar el formato de registro agregando un filtro de contexto. Mi formato es como este

FORMAT = "%(asctime)s %(VAL)s %(message)s" 

Esta es la clase que uso para establecer el VAL en el formato.

 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 

Funciona bien en un solo entorno de subprocesos, pero para un determinado entorno de subprocesos múltiples recibo el error

  

¿Alguien puede decirme que está mal aquí? y como rectificar?

Bueno, la excepción le dice que el objeto thread._local devuelto desde threading.local() no tiene un atributo de value que pueda asignar val . Puede confirmarlo agregando un dir(self.test_var) después de self.test_var=threading.local() línea. Eso me devuelve esto:

 ['__class__', '__delattr__', '__dict__', '__doc__', '__getattribute__', '__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__'] 

De hecho, help(threading.local()) le mostrará los métodos y atributos que existen, el value no está entre ellos.

Si está intentando agregar un nuevo atributo, quizás desee:

 self.test_var.__setattr__('value',val) 

Esto creará realmente el atributo y le asignará el valor.

Los atributos de instancia generalmente no se crean simplemente asignándolos, como las variables que no son de instancia son …

Los atributos de los hilos locales son por hilo. Si está creando el objeto TEST en un subproceso y ejecutando el filtro en otro, obtendría este error.

No puedo decir exactamente lo que estás tratando de hacer. Si está seguro de que desea un almacenamiento local de subprocesos, puede usar hasattr para verificar el atributo justo antes del acceso.

Prueba esto:

  def filter(self,record): if not hasattr(self.test_var, 'value'): self.test_var.value = 'some default var' record.VAL=self.test_var.value return True