Seite 1 von 1
Thread AttributeError
Verfasst: Samstag 7. Januar 2012, 11:33
von Gremlin
Code: Alles auswählen
from threading import Thread
class WorkerThread(Thread):
def run(self):
# Original ausm threading Modul
try:
if self.__target:
self.__target(*self.__args, **self.__kwargs)
finally:
# Avoid a refcycle if the thread is running a function with
# an argument that has a member that points to the thread.
del self.__target, self.__args, self.__kwargs
def worker():
while True: pass
thread = WorkerThread(target=worker)
thread.start()
Resultiert in:
Exception in thread Thread-1:
Traceback (most recent call last):
File "E:\Python27\lib\threading.py", line 552, in __bootstrap_inner
self.run()
File "G:\TEMP\blub.py", line 13, in run
del self.__target, self.__args, self.__kwargs
AttributeError: _WorkerThread__target
Kann mir das einer erklären?
Re: Thread AttributeError
Verfasst: Samstag 7. Januar 2012, 11:47
von EyDu
Hallo.
Im Original ist es nur ein Unterstrich und nicht zwei. Was versuchst du dort eigentlich? Wenn du den Thread in einer Klasse haben willst, dann kannst du auch direkt
Code: Alles auswählen
class Worker(threading.Thread):
def run(self):
while True:
pass
schreiben.
Sebastian
Re: Thread AttributeError
Verfasst: Samstag 7. Januar 2012, 13:34
von Gremlin
Ahhhh... Es handelt sich übrigens um Python 2.7 ...denn bei mir im threading Modul sinds wirklich zwei Unterstriche.
Code: Alles auswählen
# Main class for threads
class Thread(_Verbose):
...
def __init__(self, group=None, target=None, name=None,
args=(), kwargs=None, verbose=None):
assert group is None, "group argument must be None for now"
_Verbose.__init__(self, verbose)
if kwargs is None:
kwargs = {}
self.__target = target
...
Und zu deiner Frage was ich eigentlich vorhabe:
Code: Alles auswählen
class WorkerThread(Thread):
def __init__(self, group=None, target=None, name=None, args=(), kwargs=None):
Thread.__init__(self, group, target, name, args, kwargs)
self._target = target
self._args = args
self._kwargs = kwargs or {}
self._aborted = False
def run(self):
try:
if self._target:
self._target(self, *self._args, **self._kwargs)
finally:
# Avoid a refcycle if the thread is running a function with
# an argument that has a member that points to the thread.
del self._target, self._args, self._kwargs
def should_abort(self):
return self._aborted
def abort(self):
self._aborted = True
try:
self.join()
except RuntimeError:
if self.is_alive():
raise
Das funktioniert. Aber mein oben gepostetes MiniBeispiel tuts eben nicht. Wenn mir jetzt jemand erklärt warum ich die Originalattribute nicht verwenden kann, bin ich glücklich.

Re: Thread AttributeError
Verfasst: Samstag 7. Januar 2012, 14:01
von /me
Gremlin hat geschrieben:Wenn mir jetzt jemand erklärt warum ich die Originalattribute nicht verwenden kann, bin ich glücklich.

Grundsätzlich sollte man schon Attribute mit einfachem führenden Unterstrich nicht anfassen, da diese laut Konvention nicht als Teil der öffentlichen API gesehen werden. Bei Attributen mit doppelten führenden Unterstrichen bekommt man sogar extra noch mal was um die Ohren gehauen. Stichwort:
name mangling.
Lass mal folgenden Code laufen:
Code: Alles auswählen
from __future__ import print_function
class Base(object):
def __init__(self):
self.value1 = 'value 1'
self._value2 = 'value 2'
self.__value3 = 'value 3'
class Descendant(Base):
def show(self):
print(self.value1)
print(self._value2)
print(self.__value3)
inst = Descendant()
inst.show()
Re: Thread AttributeError
Verfasst: Samstag 7. Januar 2012, 14:11
von EyDu
/me hat ja bereits geschrieben, was die doppelten Unterstriche andeuten. Wenn du deren Bedeutung nicht kennst, solltest du wirklich noch einmal überlegen was du dort tust. Doppelte Unterstriche sind ein ganz deutlicher Hinweis darauf, dass man das Attribut nur anfassen sollte, wenn man wirklich genau weiß was man dort eigentlich tut.
Sehe ich das richtig, dass du bei deinem WorkerThread einfach alles aus Thread hineinkopiert hast?
Re: Thread AttributeError
Verfasst: Samstag 7. Januar 2012, 14:23
von Gremlin
Oha, die Bedeutung der Unterstriche vor einem Attribut ist mir ja eigentlich schon bekannt, aber ich war bisher der Meinung dass das nicht mehr als nur eine Richtlinie für Programmierer ist und nicht dass der Interpreter tatsächlich diese ebenfalls "beachtet". Naja, wieder was dazu gelernt. Danke.
@EyDu
Nein ich habe nicht alles kopiert. Ich habe nur die run-Methode kopiert und gebe dann dem target als erstes Argument die Instanz des Threads. Damit prüfe ich dann per "should_abort" im target ob die Verarbeitung abgebrochen werden soll oder nicht.