0

say from the following class thread_1 calls the "f1" function and my goal is that this call makes a separate thread(e.g., thread_2) to call "f2" function. What I thought was similar to the following:

from threading import Thread
class obj (object):
    def __init__(self):
        self.thr = Thread(target=self.f2, args=())
        self.thr.start()

    def f2 (self):
        print('something')

    def f1 (self):
        self.thr.run()

a = obj()
a.f1()

but this gave the following error:

    862         try:
--> 863             if self._target:
    864                 self._target(*self._args, **self._kwargs)

    AttributeError: 'Thread' object has no attribute '_target'

    During handling of the above exception, another exception occurred:

    AttributeErrorTraceback (most recent call last)
    <ipython-input-40-384ee2f45fe4> in <module>
    ----> 1 a.f2()

    <ipython-input-38-ce8946449d8c> in f2(self)
          9 
         10     def f2 (self):
    ---> 11         self.thr.run()

    /usr/lib/python3.6/threading.py in run(self)
        866             # Avoid a refcycle if the thread is running a function with
        867             # an argument that has a member that points to the thread.
    --> 868             del self._target, self._args, self._kwargs
        869 
        870     def _bootstrap(self):

    AttributeError: _target
4
  • 1
    Is that indentation correct? As in, you have a class variable that is an instance of the class itself? Commented Jun 10, 2020 at 22:56
  • @bnaecker I think the indentations are corrected now. Commented Jun 10, 2020 at 23:02
  • 1
    I edited your code to fix the problem brought up by @bnaecker. The call to create the object should be outside of the class. Let me know if I got that wrong. Commented Jun 10, 2020 at 23:06
  • @tdelaney, thanks, it was a typo while writing the question. the issue with the error though was not related to the indentation/ Commented Jun 10, 2020 at 23:08

1 Answer 1

3

The problem is that you call self.thr.run(). When a thread is created it will call run in the new thread to implement your thread's functionality. You can override that method or let its default behavior of running self._thread just run the function you passed in the constructor.

This method is not meant to be called outside of the thread logic. When the thread ends, self._target is deleted. Thread objects can't be recycled and this is part of setting up a tripwire when that happens. (more technically, I think it is getting rid of references at thread completion considering that the thread object itself may be abandoned by less than tidy client code).

When you called it manually in your code the thread had already completed and _target was gone.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.