Dlaczego otrzymuję błąd AttributeError: Obiekt nie ma atrybutu [zamknięte]


82

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


Czy opublikowałby cały błąd ze stosem wywołań?
lenistwo

czy mógłbyś dodać kod, jak dzwonisz?
Babu,

2
Brakuje jakiegoś kodu. Ten fragment działa dobrze dla mnie.
ThirdOne

2
Jest mi ogromnie przykro. Tak, moje wcięcie zostało oszukane. Całkowicie nowicjusz w Pythonie. Więc mógł przegapić krytyczność wcięcia.
Shades88

podczas kodowania Pythona należy wybrać opcję „Pokaż tabulatory i spacje” w edytorze kodu
vanduc1102

Odpowiedzi:


94

Twoje wcięcie jest błędne i pomieszałeś tabulatory i spacje. Uruchom skrypt, python -ttaby zweryfikować.


Dzięki za ten otwieracz do oczu. Teraz to rozumiem. Przepraszam za głupie pytanie i zbyt długie wyjaśnienie takiego pytania;)
Shades88

3
Czy mógłbyś mi powiedzieć, jakie jest znaczenie „Uruchom skrypt za pomocą python -tt, aby zweryfikować”?
akshay_rahar

9
@akshay_rahar:python -tt script.py
Ignacio Vazquez-Abrams

1
Więc co robi ten magiczny parametr -tt? Nie znalazłem tego w dokumentach
Łukasz Nojek

10
Aktualizacja: -ttflaga nie występuje w Pythonie 3, była w Pythonie 2.
Łukasz Nojek

13

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.


Czy jest to udokumentowane w PIP?
przerywany

1
po prostu natknąłem się na problem i znalazłem ten komentarz, dlaczego mieliby to tak zaprojektować?
matthewhang


12

Tego rodzaju błędy są powszechne w przypadku wielowątkowości Pythona. Dzieje się tak, że po usunięciu tłumacza odpowiedni moduł ( myThreadw tym przypadku) przechodzi coś w rodzaju del myThread.

Wywołanie self.sample()jest z grubsza równoważne z myThread.__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ć myThreadusunięty, a teraz jest w zasadzie a NoneType- i nie ma atrybutu „sample”.


7

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'

2

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.


1

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.


0

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.


Możesz publikować polecenia ponownego uruchomienia lub cokolwiek zrobiłeś. Może to być pomocne dla początkujących.
Khan

0

Ten sam błąd wystąpił, gdy miałem inną zmienną o nazwie mythread. Ta zmienna nadpisała to i dlatego mam błąd


-3

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.


3
Autor nie próbuje uzyskać dostępu do metody prywatnej, pytanie również ma ponad 6 lat i zostało już rozwiązane, więc nie ma potrzeby ponownego odpowiadania na nie.
Johan
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.