title: Dynamically inserting a function into a Python class
body: <p>I am writing a metaclass that amongst other things wants to add a method to the classes it creates. Let's forget about the metaclass for now though and just look at simple adding of methods.</p>
  
  <p>In order to dynamically add an instance method I can do:</p>
  
  <pre><code>class Foo:
      def bar(self, x):
          print(f"In bar() with {x} and {self}")
  
  def func(self, x):
      print(f"In func() with {x} and {self}")
  
  Foo.func = func
  </code></pre>
  
  <p>After that I can do:</p>
  
  <pre><code>&gt;&gt;&gt; f = Foo()                                                                                                                                              
  &gt;&gt;&gt; f.bar(7)                                                                                                                                               
  In bar() with 7 and &lt;__main__.Foo object at 0x7f912a7e57f0&gt;                                                                                                
  &gt;&gt;&gt; f.func(7)                                                                                                                                              
  In func() with 7 and &lt;__main__.Foo object at 0x7f912a7e57f0&gt;
  </code></pre>
  
  <p>So the methods <code>bar</code> and <code>func</code> seem to function identically, but there are some discernible differences, e.g.:</p>
  
  <pre><code>&gt;&gt;&gt; f.bar.__qualname__                                                                                                                                     
  'Foo.bar'                                                                                                                                                  
  &gt;&gt;&gt; f.func.__qualname__                                                                                                                                 
  'func'
  </code></pre>
  
  <p><code>f.func.__module__</code> could also potentially be different from <code>f.bar.__module__</code>, depending on where everything is defined.</p>
  
  <p>What do I have to change in Construction 2 (below) in order for both constructions to behave exactly the same (no code that uses the <code>Foo</code> class could change its behaviour depending on which construction is used)?</p>
  
  <pre><code># Construction 1
  class Foo:
      def func(self):
          pass
  
  # Construction 2
  class Foo:
      pass
  def func(self):
      pass
  Foo.func = func
  </code></pre>
  
  <p>I have created a decorator that hopefully implements a sensible version of Construction 2, but what could I still be missing/breaking by monkey patching like that?</p>
  
  <pre><code>class instance_method_of:
  
      def __init__(self, cls, name=None):
          self.cls = cls
          self.name = name
  
      def __call__(self, func):
          if self.name is not None:
              func.__name__ = self.name
          func.__qualname__ = f'{self.cls.__qualname__}.{func.__name__}'
          func.__module__ = self.cls.__module__
          setattr(self.cls, func.__name__, func)
          return func
  
  class Foo:
      pass
  
  @instance_method_of(Foo)
  def func(self):
      pass
  </code></pre>