title: Python: Getting the name of a callable function argument
body: <p>How would I get the string representation of a callable function passed as an argument to another?</p>
  
  <pre><code>def foo():
      print("This is my callback function")
  
  def bar(callback=None):
      print(*something*)
  
  bar(foo)
  </code></pre>
  
  <p>I would like to have in my <code>bar()</code> somehow access to the actual name <code>foo</code> as a string. I thought about <code>__name__</code> but it does not work quite as expected in my case:</p>
  
  <p>The reason I need to do this is that I am trying to add a networking layer on top of existing code, so that the code could either be local, or partially remote. And as the underlying data model is used in many applications and locations, I thought to add a "mock" class layer, and implementing the remote execution would just require a different import statement importing my mock classes that would do remotely some parts of the code. </p>
  
  <p>And as the model is in development, I did not want to implement one to one copy of the original classes but just a <code>__getattr__()</code> hack to have the mock class respond to any method that might be called, and pass that to the remote side to be reconstructed there. </p>
  
  <p>I was astonished this actually works rather nicely, but now I have a problem with certain callback functions that need to be executed on the remote side. I only need to know their names, not the actual instances, as I need to create the callback structure on the remote side based on information sent there over the network.</p>
  
  <p>Consider this class (that does not work correctly in this sense):</p>
  
  <pre><code>class Remote1(RemoteExec):
      kind = "Remote1"
  
      def __init__(self, parent, *args, **kwargs):
          super().__init__(parent, *args, **kwargs)
          self.parent.children.append({"kind": Remote1, "link": self})
  
      def __getattr__(self, name):
          def foo(*args, **kwargs):
              key = name
              for _a in args:
                  key += str(_a)
  
              _kwa = {}
              for k, v in kwargs.items():
                  if callable(v):
                      _remotename = v.__name__
                      _kwa[k] = _remotename
                      print(k, v, _remotename)
                      continue
                  else:
                      _kwa[k] = v
              self.functions[key] = {"func": name, "args": args, "kwargs": kwargs}
          return foo
  </code></pre>
  
  <p>and class <code>Remote2</code> that would be identical to <code>Remote1</code>.  Now if I have</p>
  
  <pre><code>r1 = Remote1()
  r2 = Remote2()
  r2.add_callback(callback=r1.callback)
  </code></pre>
  
  <p>I would need to recreate this on the remote side. Now the problem is getting enough information to be transmitted over. My print statement  returns this, without any reference to <code>callback()</code>:</p>
  
  <pre><code>callback &lt;function Remote1.__getattr__.&lt;locals&gt;.foo at 0x7f8148489048&gt; foo
  </code></pre>
  
  <p>as the <code>callback()</code> function as such did not exist but was caught by the getattr hack, and the function name got replaced by <code>foo()</code> within. </p>
  
  <p>How can I get something sensible in my <code>remotename</code>, basically the string representation of what was passed as an argument despite it being a callable?</p>