0

When I run the following program:

import threading
class foo(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)
    def __enter__(self):
        print "Enter"
    def __exit__(self, type, value, traceback):
        print "Exit"

    def run():
        print "run"



if __name__ == "__main__":
    with foo() as f:
        f.start()

I get this as the output

C:\>python test2.py
Enter
Exit
Traceback (most recent call last):
  File "test2.py", line 17, in <module>
    f.start()
AttributeError: 'NoneType' object has no attribute 'start'

Is there any way to combine the with keyword's guaranteed cleanup code execution with a threaded class?

Strill
  • 228
  • 3
  • 10

2 Answers2

4
import threading
class foo(threading.Thread):
    def __enter__(self):
        print "Enter"
        return self
    def __exit__(self, type, value, traceback):
        self.join() # wait for thread finished
        print "Exit"
    def run(self):
        print "run"

if __name__ == "__main__":
    with foo() as f:
        f.start()

Your __enter__ method should return self; that's what gets assigned to the variable in the with ... as f construct.

Having the thread join in __exit__ as suggested by @linjunhalida is also a good idea, but not causing your current problem.

You should also change the definition of run to def run(self) if you want it to be usable. :)

Community
  • 1
  • 1
Danica
  • 28,423
  • 6
  • 90
  • 122
-3

Simply wait thread finish execution by using join: http://docs.python.org/library/threading.html#threading.Thread.join

import threading
class foo(threading.Thread):
    def __init__(self):
        self.thread = threading.Thread.__init__(self)
    def __enter__(self):
        print "Enter"
    def __exit__(self, type, value, traceback):
        self.thread.join() # wait for thread finished
        print "Exit"

    def run():
        print "run"



if __name__ == "__main__":
    with foo() as f:
        f.start()
linjunhalida
  • 4,538
  • 6
  • 44
  • 64