Mam klasę MyThread. W tym mam próbkę metody. Próbuję uruchomić go z tego samego kontekstu obiektu. Proszę spojrzeć na kod:
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()
Wygląda na bardzo proste, prawda? Ale kiedy go uruchamiam, pojawia się ten błąd
AttributeError: 'myThread' object has no attribute 'sample'
Teraz mam tę metodę, właśnie tam. Więc co się stało? Proszę pomóż
Edycja: to jest ślad stosu
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'
Ja to tak nazywam
arThreads = []
maxThreads = 2;
for i in range( maxThreads ):
redisOpsObj = redisOps()
arThreads.append( myThread(i, "Thread-"+str(i), 10, redisOpsObj) )
Przepraszamy, nie mogę wysłać kodu klasy redisOps. Ale mogę cię zapewnić, że działa dobrze
Odpowiedzi:
Twoje wcięcie jest błędne i pomieszałeś tabulatory i spacje. Uruchom skrypt,
python -tt
aby zweryfikować.źródło
python -tt script.py
-tt
? Nie znalazłem tego w dokumentach-tt
flaga nie występuje w Pythonie 3, była w Pythonie 2.Jeśli używasz Pythona 3+, może się to również zdarzyć, jeśli używasz prywatnych zmiennych, które zaczynają się od podwójnego podkreślenia, np. Self .__ yourvariable. Po prostu coś, na co warto zwrócić uwagę dla niektórych z was, którzy mogą napotkać ten problem.
źródło
Tego rodzaju błędy są powszechne w przypadku wielowątkowości Pythona. Dzieje się tak, że po usunięciu tłumacza odpowiedni moduł (
myThread
w tym przypadku) przechodzi coś w rodzajudel myThread
.Wywołanie
self.sample()
jest z grubsza równoważne zmyThread.__dict__["sample"](self)
. Ale jeśli jesteśmy w trakcie sekwencji zrywania interpretera, to jego własny słownik znanych typów mógł już zostaćmyThread
usunięty, a teraz jest w zasadzie aNoneType
- i nie ma atrybutu „sample”.źródło
Może się to również zdarzyć, jeśli używasz slotów w klasie i nie dodałeś jeszcze tego nowego atrybutu do slotów.
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'
źródło
Otrzymałem ten błąd dla scenariusza wielowątkowego (szczególnie w przypadku ZMQ). Okazało się, że gniazdo nadal jest połączone w jednym wątku, podczas gdy inny wątek już zaczął przesyłać dane. Zdarzenia, które wystąpiły z powodu innego wątku, próbowały uzyskać dostęp do zmiennych, które nie zostały jeszcze utworzone. Jeśli twój scenariusz obejmuje wielowątkowość i jeśli coś działa, jeśli dodasz trochę opóźnienia, możesz mieć podobny problem.
źródło
Python chroni tych członków, zmieniając wewnętrznie nazwę, tak aby zawierała nazwę klasy. Możesz uzyskać dostęp do takich atrybutów, jak object._className__attrName.
źródło
Napotkałem również ten sam błąd. Jestem pewien, że moje wgłębienie nie miało żadnego problemu. Dopiero ponowne uruchomienie sprzedaży Pythona rozwiązało problem.
źródło
Ten sam błąd wystąpił, gdy miałem inną zmienną o nazwie mythread. Ta zmienna nadpisała to i dlatego mam błąd
źródło
Nie możesz uzyskać dostępu poza prywatnymi polami zajęć. pola prywatne zaczynają się od __. na przykład -
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 to metoda prywatna.
źródło