Ответ 1
Отступы вычеркнуты, и вы смешали вкладки и пробелы. Запустите script с помощью python -tt
, чтобы проверить.
У меня есть класс 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. Но я могу заверить вас, что это работает просто отлично
Отступы вычеркнуты, и вы смешали вкладки и пробелы. Запустите script с помощью python -tt
, чтобы проверить.
Такие ошибки часто встречаются при многопоточности Python. Случается, что при разрыве интерпретатора соответствующий модуль (myThread
в этом случае) проходит через сортировку del myThread
.
Вызов self.sample()
примерно эквивалентен myThread.__dict__["sample"](self)
.
Но если мы находимся во время срывной последовательности интерпретатора, то его собственный словарь известных типов, возможно, уже удалил myThread
, а теперь он в основном NoneType
- и не имеет атрибута 'sample'.
Если вы используете python 3>, это может также произойти, если вы используете закрытые переменные, которые начинаются с двойного подчеркивания, например self.__ yourvariable, просто кое-что, на что стоит обратить внимание некоторым из вас, кто может столкнуться с этой проблемой
Это также может произойти, если вы используете слоты в классе и еще не добавили этот новый атрибут в слоты.
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'
Python защищает этих членов, внутренне меняя имя, чтобы включить имя класса. Вы можете получить доступ к таким атрибутам, как object._className__attrName.
Я получил эту ошибку для многопоточного сценария (особенно при работе с ZMQ). Оказалось, что сокет все еще был подключен к одному потоку, в то время как другой поток уже начал отправлять данные. События, произошедшие из-за другого потока, пытались получить доступ к переменным, которые еще не были созданы. Если ваш сценарий предполагает многопоточность и если все работает, если вы добавите немного задержки, то у вас может быть похожая проблема.
Я также столкнулся с той же ошибкой. Я уверен, что у моего отступа не было никаких проблем. Только перезапуск Python Sell решил проблему.
Та же ошибка произошла, когда у меня была другая переменная с именем mythread. Эта переменная перезаписала это и вот почему я получил ошибку
Вы не можете получить доступ к закрытым полям класса. закрытые поля начинаются с __. например -
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 - это приватный метод.