Warum erhalte ich AttributeError: Objekt hat kein Attribut [geschlossen]

81

Ich habe eine Klasse MyThread. Darin habe ich ein Methodenbeispiel. Ich versuche, es aus demselben Objektkontext heraus auszuführen. Bitte schauen Sie sich den Code an:

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()

Sieht sehr einfach aus, nicht wahr? Aber wenn ich es starte, bekomme ich diesen Fehler

AttributeError: 'myThread' object has no attribute 'sample'Jetzt habe ich genau dort diese Methode. Also, was ist falsch? Bitte helfen Sie

Bearbeiten: Dies ist die Stapelverfolgung

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'

Ich nenne es so

arThreads = []
maxThreads = 2;

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

Leider kann ich keinen redisOps-Klassencode veröffentlichen. Aber ich kann Ihnen versichern, dass es gut funktioniert

Shades88
quelle
Würde der komplette Fehler mit dem Callstack posten?
Faultier
Könnten Sie bitte den Code hinzufügen, wie Sie anrufen?
Babu
2
Fehlt Code? Dieser Ausschnitt funktioniert fien für mich.
ThirdOne
2
Es tut mir sehr leid. Ja, meine Einrückung wurde getäuscht. Völlig Neuling in Python. Möglicherweise wurde die Kritikalität der Einrückung übersehen.
Shades88
Während Sie Python codieren, sollten Sie in Ihrem Code-Editor "Tabulatoren und Leerzeichen
anzeigen

Antworten:

92

Ihre Einrückung ist vermasselt und Sie haben Tabulatoren und Leerzeichen gemischt. Führen Sie das Skript python -ttzur Überprüfung mit aus.

Ignacio Vazquez-Abrams
quelle
Danke für diesen Augenöffner. Ich habe es verstanden. Entschuldigung für die dumme Frage und die zu lange Erklärung einer solchen Frage;)
Shades88
3
Würden Sie mir bitte sagen, was die Bedeutung von "Führen Sie das Skript mit python -tt aus, um dies zu überprüfen" bedeutet.
akshay_rahar
9
@akshay_rahar:python -tt script.py
Ignacio Vazquez-Abrams
1
Was macht dieser magische Parameter -tt? Ich habe es nicht in den Dokumenten gefunden
Łukasz Nojek
8
Update: -ttFlag ist in Python 3 nicht vorhanden, es war in Python 2.
Łukasz Nojek
12

Diese Art von Fehlern tritt häufig beim Python-Multithreading auf. Was passiert, ist, dass das relevante Modul ( myThreadin diesem Fall) beim Abreißen des Interpreters eine Art durchläuft del myThread.

Der Anruf self.sample()entspricht in etwa myThread.__dict__["sample"](self). Wenn wir uns jedoch während der Abreißsequenz des Interpreters befinden, wurde möglicherweise bereits ein eigenes Wörterbuch bekannter Typen myThreadgelöscht, und jetzt ist es im Grunde ein NoneType- und hat kein 'Beispiel'-Attribut.

Trevor
quelle
11

Wenn Sie Python 3+ verwenden, kann dies auch auftreten, wenn Sie private Variablen verwenden, die mit einem doppelten Unterstrich beginnen, z. B. self .__ yourvariable. Nur etwas, das Sie für einige von Ihnen beachten sollten, die möglicherweise auf dieses Problem stoßen.

Timothy Mugayi
quelle
Ist es in einem PIP dokumentiert?
Bindestrich
1
Laufen Sie einfach auf das Problem und finden Sie diesen Kommentar. Warum sollten sie ihn so gestalten?
Matthewhang
7

Dies kann auch auftreten, wenn Sie Slots in der Klasse verwenden und dieses neue Attribut noch nicht in Slots hinzugefügt haben.

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
quelle
2

Ich habe diesen Fehler für ein Multithreading-Szenario erhalten (speziell beim Umgang mit ZMQ). Es stellte sich heraus, dass der Socket noch mit einem Thread verbunden war, während ein anderer Thread bereits mit dem Senden von Daten begann. Die Ereignisse, die aufgrund eines anderen Threads aufgetreten sind, haben versucht, auf Variablen zuzugreifen, die noch nicht erstellt wurden. Wenn Ihr Szenario Multithreading umfasst und die Dinge funktionieren, wenn Sie etwas Verzögerung hinzufügen, liegt möglicherweise ein ähnliches Problem vor.

Shital Shah
quelle
1

Python schützt diese Mitglieder, indem der Name intern so geändert wird, dass er den Klassennamen enthält. Sie können auf Attribute wie object._className__attrName zugreifen.

Shyam Gupta
quelle
0

Ich habe den gleichen Fehler auch festgestellt. Ich bin sicher, dass meine Einrückung kein Problem hatte. Nur ein Neustart des Python-Verkaufs löste das Problem.

Mohammad Sadoughi
quelle
Sie können Befehle zum Neustart veröffentlichen oder was auch immer Sie getan haben. Es könnte für Anfänger hilfreich sein.
Khan
0

Der gleiche Fehler trat auf, als ich eine andere Variable namens mythread hatte. Diese Variable hat dies überschrieben und deshalb habe ich einen Fehler bekommen

Remobob
quelle
-3

Sie können nicht auf private Felder einer Klasse zugreifen. Private Felder beginnen mit __. zum Beispiel -

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 ist eine private Methode.

Mukesh Yadav
quelle
2
Der Autor versucht nicht, auf eine private Methode zuzugreifen. Die Frage ist ebenfalls älter als 6 Jahre und bereits gelöst, sodass Sie nicht versuchen müssen, sie erneut zu beantworten.
Johan