title: Assigning a method to an object as a variable
body: <p>I wanted objects to call a certain method (the specific one being assigned in a variable) in their routine. I managed to do it with a dict and I also managed to do it by assigning the variable after object creation. Which way is better? Is there another cleaner way?</p>
  <p>First way that works (dict):</p>
  <pre><code>class Foo:
      def __init__(self, name, funcin) -&gt; None:
          self.name = name
          self.func = {
              'bear': self.bear,
              'boar': self.boar,
          }[funcin]
      
      def routine(self):
          print('fluff')
          self.func()
  
      def bear(self):
          print(f'I, {self.name}, am a bear and I like honey.')
      
      def boar(self):
          print(f'I, {self.name}, am a boar and I like fruits.')
  
  bob = Foo('bob', 'bear')
  mark = Foo('mark', 'boar')
  
  bob.routine()
  mark.routine()
  </code></pre>
  <p>Second way that worked (another line to assign):</p>
  <pre><code>class Foo:
      def __init__(self, name) -&gt; None:
          self.name = name
      
      def routine(self):
          print('fluff')
          self.func()
  
      def bear(self):
          print(f'I, {self.name}, am a bear and I like honey.')
      
      def boar(self):
          print(f'I, {self.name}, am a boar and I like fruits.')
      
  Kona = Foo('Kona')
  Kona.func = Kona.bear
  John = Foo('John')
  John.func = John.boar
  
  Kona.routine()
  John.routine()
  </code></pre>
  <p>Ways that didn't work:</p>
  <pre><code># NameError: name 'bear' is not defined
  class Foo:
      def __init__(self, name, funcin) -&gt; None:
          self.name = name
          self.func = self.funcin
      def bear(self):
          print(f'I, {self.name}, am a bear and I like honey.')
  bob = Foo('bob', bear)
  bob.func()
  
  # NameError: name 'self' is not defined
  class Foo:
      def __init__(self, name, funcin) -&gt; None:
          self.name = name
          self.func = funcin
      def bear(self):
          print(f'I, {self.name}, am a bear and I like honey.')
  bob = Foo('bob', self.bear)
  bob.func()
  
  # NameError: name 'Kim' is not defined
  class Foo:
      def __init__(self, name, funcin) -&gt; None:
          self.name = name
          self.func = funcin
      def bear(self):
          print(f'I, {self.name}, am a bear and I like honey.')
  Kim = Foo('Kim', Kim.bear)
  Kim.func()   
  
  # TypeError: Foo.bear() missing 1 required positional argument: 'self'
  class Foo:
      def __init__(self, name, funcin) -&gt; None:
          self.name = name
          self.func = funcin
      def bear(self):
          print(f'I, {self.name}, am a bear and I like honey.')
  bob = Foo('bob', Foo.bear)
  bob.func()
  </code></pre>