title: Accessing `self` from thread target
body: <p>According to a number of sources, including <a href="https://stackoverflow.com/q/660961/2988730">this question</a>, passing a runnable as the <code>target</code> parameter in <a href="https://docs.python.org/3/library/threading.html#threading.Thread" rel="nofollow noreferrer"><code>__init__</code></a> (with or without <code>args</code> and <code>kwargs</code>) is preferable to extending the <code>Thread</code> class.</p>
  
  <p>If I create a runnable, how can I pass the thread it is running on as <code>self</code> to it without extending the <code>Thread</code> class? For example, the following would work fine:</p>
  
  <pre><code>class MyTask(Thread):
      def run(self):
          print(self.name)
  MyTask().start()
  </code></pre>
  
  <p>However, I can't see a good way to get this version to work:</p>
  
  <pre><code>def my_task(t):
      print(t.name)
  Thread(target=my_task, args=(), kwargs={}).start()
  </code></pre>
  
  <p>This question is a followup to <a href="https://stackoverflow.com/q/47912701/2988730">Python - How can I implement a &#39;stoppable&#39; thread?</a>, which I answered, but possibly incompletely.</p>
  
  <p><strong>Update</strong></p>
  
  <p>I've thought of a hack to do this using <a href="https://docs.python.org/3/library/threading.html#threading.current_thread" rel="nofollow noreferrer"><code>current_thread()</code></a>:</p>
  
  <pre><code>def my_task():
      print(current_thread().name)
  Thread(target=my_task).start()
  </code></pre>
  
  <p>Problem: calling a function to get a parameter that should ideally be passed in.</p>
  
  <p><strong>Update #2</strong></p>
  
  <p>I have found an even hackier solution that makes <code>current_thread</code> seem much more attractive:</p>
  
  <pre><code>class ThreadWithSelf(Thread):
      def __init__(self, **kwargs):
          args = kwargs.get('args', ())
          args = (self,) + tuple(args)
          kwargs[args] = args
          super().__init__(**kwargs)
  ThreadWithSelf(target=my_task).start()
  </code></pre>
  
  <p>Besides being incredibly ugly (e.g. by <em>forcing</em> the user to use keywords only, even if that is the recommended way in the documentation), this completely defeats the purpose of not extending <code>Thread</code>.</p>
  
  <p><strong>Update #3</strong></p>
  
  <p>Another ridiculous (and unsafe) solution: to pass in a mutable object via <code>args</code> and to update it afterwards:</p>
  
  <pre><code>def my_task(t):
      print(t[0].name)
  container = []
  t = Thread(target=my_task, args=(container,))
  container[0] = t
  t.start()
  </code></pre>
  
  <p>To avoid synchronization issues, you could kick it up a notch and implement another layer of ridiculousness:</p>
  
  <pre><code> def my_task(t, i):
       print(t[i].name)
   container = []
   container[0] = Thread(target=my_task, args=(container, 0))
   container[1] = Thread(target=my_task, args=(container, 1))
   for t in container:
       t.start()
  </code></pre>
  
  <p>I am still looking for a legitimate answer.</p>