¿Por qué obtengo AttributeError: el objeto no tiene ningún atributo [cerrado]

81

Tengo una clase MyThread. En eso tengo una muestra de método. Estoy tratando de ejecutarlo desde el mismo contexto de objeto. Por favor, mire el código:

class myThread (threading.Thread):
    def __init__(self, threadID, name, counter, redisOpsObj):
        threading.Thread.__init__(self)
        self.threadID = threadID
        self.name = name
        self.counter = counter
        self.redisOpsObj = redisOpsObj

    def stop(self):
        self.kill_received = True

    def sample(self):
        print "Hello"

    def run(self):
        time.sleep(0.1)
        print "\n Starting " + self.name
        self.sample()

Parece muy simple, ¿no? Pero cuando lo ejecuto, aparece este error.

AttributeError: 'myThread' object has no attribute 'sample'Ahora tengo ese método, ahí mismo. ¿Así que qué hay de malo? Por favor ayuda

Editar: este es el stacktrace

Starting Thread-0

Starting Thread-1
Exception in thread Thread-0:
Traceback (most recent call last):
File "/usr/lib/python2.6/threading.py", line 525, in __bootstrap_inner
self.run()
File "./redisQueueProcessor.py", line 51, in run
self.sample()
AttributeError: 'myThread' object has no attribute 'sample'

Exception in thread Thread-1:
Traceback (most recent call last):
File "/usr/lib/python2.6/threading.py", line 525, in __bootstrap_inner
self.run()
File "./redisQueueProcessor.py", line 51, in run
self.sample()
AttributeError: 'myThread' object has no attribute 'sample'

Lo estoy llamando así

arThreads = []
maxThreads = 2;

for i in range( maxThreads ):
    redisOpsObj = redisOps()
    arThreads.append( myThread(i, "Thread-"+str(i), 10, redisOpsObj) )

Lo siento, no puedo publicar el código de clase de redisOps. Pero puedo asegurarte que funciona bien

Sombras88
fuente
¿Publicaría el error completo con la pila de llamadas?
perezoso
¿Podría agregar el código de cómo está llamando?
Babu
2
¿Falta algún código? Este fragmento me funciona muy bien.
ThirdOne
2
Lo siento mucho. Sí, mi sangría fue engañada. Totalmente novato en Python. Así que podría haber pasado por alto la importancia crítica de la sangría.
Shades88
mientras codifica Python, debe elegir "Mostrar pestañas y espacios" en su editor de código
vanduc1102

Respuestas:

92

Su sangría es errónea y ha mezclado tabulaciones y espacios. Ejecute el script con python -ttpara verificar.

Ignacio Vázquez-Abrams
fuente
Gracias por esa revelación. Ya lo pillo. Perdón por la pregunta estúpida y la explicación demasiado larga de tal pregunta;)
Shades88
3
¿Podría decirme cuál es el significado de "Ejecutar el script con python -tt para verificar"?
akshay_rahar
9
@akshay_rahar:python -tt script.py
Ignacio Vazquez-Abrams
1
Entonces, ¿qué hace este parámetro mágico -tt? No lo he encontrado en los documentos
Łukasz Nojek
8
Actualización: la -ttbandera no está presente en Python 3, estaba en Python 2.
Łukasz Nojek
12

Este tipo de errores son comunes cuando Python multi-threading. Lo que sucede es que, al desmontar el intérprete, el módulo correspondiente ( myThreaden este caso) pasa por una especie de del myThread.

La llamada self.sample()es aproximadamente equivalente a myThread.__dict__["sample"](self). Pero si estamos durante la secuencia de eliminación del intérprete, es posible que su propio diccionario de tipos conocidos ya se haya myThreadeliminado, y ahora es básicamente un NoneTypeatributo de "muestra" y no tiene.

Trevor
fuente
11

Si está usando Python 3+, esto también puede ocurrir si está usando variables privadas que comienzan con doble subrayado, por ejemplo, self .__ yourvariable. Solo algo para tomar nota para algunos de ustedes que pueden encontrarse con este problema.

Timothy Mugayi
fuente
¿Está documentado en un PIP?
elegante
1
simplemente encontré el problema y encontré este comentario, ¿por qué lo diseñarían así?
matthewhang
7

Esto también puede ocurrir si usa espacios en la clase y aún no ha agregado este nuevo atributo en los espacios.

class xyz(object):
"""
class description

"""

__slots__ = ['abc', 'ijk']

def __init__(self):
   self.abc = 1
   self.ijk = 2
   self.pqr = 6 # This will throw error 'AttributeError: <name_of_class_object> object has no attribute 'pqr'
Mitendra
fuente
2

Recibí este error para el escenario de subprocesos múltiples (específicamente cuando se trata de ZMQ). Resultó que el socket todavía estaba conectado en un hilo mientras que otro hilo ya comenzaba a enviar datos. Los eventos que ocurrieron debido a otro hilo intentaron acceder a variables que aún no se crearon. Si su escenario implica subprocesos múltiples y si las cosas funcionan si agrega un poco de retraso, es posible que tenga un problema similar.

Shital Shah
fuente
1

Python protege a esos miembros cambiando internamente el nombre para incluir el nombre de la clase. Puede acceder a atributos como object._className__attrName.

Shyam Gupta
fuente
0

También he encontrado el mismo error. Estoy seguro de que mi sangría no tuvo ningún problema. Solo reiniciar la venta de Python resolvió el problema.

Mohammad Sadoughi
fuente
Puede publicar comandos para reiniciar o lo que sea que haya hecho. Puede ser útil para los principiantes.
Khan
0

El mismo error ocurrió cuando tuve otra variable llamada mythread. Esa variable sobrescribió esto y es por eso que tengo un error

remobob
fuente
-3

No puede acceder a campos privados externos de una clase. los campos privados comienzan con __. por ejemplo -

class car:
    def __init__(self):
        self.__updatesoftware()

    def drive(self):
        print("driving")

    def __updatesoftware(self):
        print("updating software:")

obj = car()
obj.drive()  
obj.__updatesoftware()  ## here it will throw an error because 

__updatesoftware es un método privado.

mukesh yadav
fuente
2
El autor no está tratando de acceder a un método privado, la pregunta también tiene más de 6 años y ya está resuelta, por lo que no es necesario intentar responderla nuevamente.
Johan