Чому я отримую AttributeError: Об’єкт не має атрибута [закрито]


82

У мене є клас MyThread. У цьому я маю зразок методу. Я намагаюся запустити його з того самого контексту об'єкта. Подивіться на код:

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

Виглядає дуже просто, чи не так. Але при запуску я отримую цю помилку

AttributeError: 'myThread' object has no attribute 'sample'Зараз я маю цей метод, саме там. То що не так? Будь ласка, допоможіть

Редагувати: це стек

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'

Я називаю це так

arThreads = []
maxThreads = 2;

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

На жаль, я не можу опублікувати код класу redisOps. Але я можу запевнити вас, що це працює чудово


Опублікував би повну помилку зі списком викликів?
лінивець

не могли б ви додати код, як ви телефонуєте?
Бабу,

2
Чи відсутній якийсь код. Цей фрагмент працює для мене.
Третє

2
Мені дуже шкода. Так, мій відступ обдурили. Зовсім новачок у python. Тому міг пропустити критичність відступу.
Shades88,

під час кодування Python, вам слід вибрати "Показати вкладки та пробіли" у своєму редакторі коду
vanduc1102

Відповіді:


94

Ваш відступ дурний, і ви змішали вкладки та пробіли. Запустіть сценарій з python -ttдля перевірки.


Дякую за цей відкривач очей. Зрозумів зараз. Вибачте за дурне запитання та занадто довге пояснення такого питання;)
Shades88,

3
Скажіть, будь ласка, що означає "Запустити скрипт за допомогою python -tt для перевірки"?
akshay_rahar

9
@akshay_rahar:python -tt script.py
Ігнасіо Васкес-Абрамс

1
Отже, що робить цей магічний параметр -tt? Я не знайшов цього в документах
Łukasz Nojek

10
Оновлення: -ttпрапор відсутній у Python 3, він був у Python 2.
Łukasz Nojek

13

Якщо ви використовуєте python 3+, це також може статися, якщо ви використовуєте приватні змінні, які починаються з подвійним підкресленням, наприклад, self .__ yourvariable. Просто щось на замітку для деяких із вас, хто може зіткнутися з цим питанням.


Це задокументовано в PIP?
dashesy

1
просто натрапив на проблему і знайшов цей коментар, чому вони так його розробляють?
matthewhang


12

Такі помилки є типовими, коли Python багатопоточний. Що трапляється, так це те, що при розриві інтерпретатора відповідний модуль ( myThreadу даному випадку) проходить своєрідну процедуру del myThread.

Дзвінок self.sample()приблизно еквівалентний myThread.__dict__["sample"](self). Але якщо ми знаходимось під час послідовності руйнування інтерпретатора, то його власний словник відомих типів, можливо, вже був myThreadвидалений, і тепер він, по суті, є NoneType- і не має атрибута 'sample'.


7

Це також може статися, якщо ви використовуєте слоти в класі і ще не додали цей новий атрибут у слоти.

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

Я отримав цю помилку для багатопотокового сценарію (зокрема, коли маю справу з ZMQ). Виявилося, що сокет все ще підключався до одного потоку, тоді як інший потік вже почав надсилати дані. Події, що відбулися через інший потік, намагалися отримати доступ до змінних, які ще не були створені. Якщо ваш сценарій передбачає багатопоточність, і якщо щось працює, якщо ви додасте трохи затримки, можливо, у вас є схожа проблема.


1

Python захищає цих членів шляхом внутрішньої зміни імені, включаючи ім'я класу. Ви можете отримати доступ до таких атрибутів, як object._className__attrName.


0

Я також зіткнувся з тією ж помилкою. Я впевнений, що у мого відступу не було жодних проблем. Проблему вирішив лише перезапуск продажу python.


Ви можете публікувати команди для перезапуску або що завгодно. Це може бути корисно для початківців.
Хан,

0

Така сама помилка сталася, коли у мене була інша змінна з назвою mythread. Ця змінна переписала це, і тому я отримав помилку


-3

Ви не можете отримати доступ до приватних полів класу. приватні поля починаються з __. наприклад -

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 - це приватний метод.


3
Автор не намагається отримати доступ до приватного методу, питання також має більше 6 років і вже вирішено, тому немає необхідності намагатись відповісти на нього ще раз.
Йохан
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.