Question: I have a python class, let's call it `MyClass`, with several bound methods. I need the behaviour of one of these methods, call it `.dynamic_method()`, to be drastically different depending on the value of a parameter set during object creation. There will be a handful of variations of `dynamic_method` which will share very little code between them, so it makes sense to define them as separate functions/methods rather than as a single large method with many options and conditionals. I do not need to be able to change the behaviour of this method after creating the object, everything can be set during `__init__()`. 

For reference, `MyClass` manages data sets, and `.dynamic_method` deals with some IO aspects of this data which change depending on dataset and context.

This is not technically difficult to achieve, but none of the methods I've come up with feel completely correct:

1. Define the method variations as functions separately, and attach one of them as a bound method during `__init__()` using one of the methods described here: [Adding a Method to an Existing Object Instance](https://stackoverflow.com/questions/972/adding-a-method-to-an-existing-object-instance). This seems like the most natural choice to me, but many of the answers in that thread strongly discourages the use of this pattern.
2. Define all possible methods in the class definition as `.dynamic_method_a`, `.dynamic_method_b` etc, and set an option/alias so that `MyClass.dynamic_method()` calls the correct one. This will result in a very long class definition, and lots of unused methods for each object.
3. Store the methods as separate functions, and have `.dynamic_method()` simply calls the correct function with `self` as the first argument. This feels like a wilful misuse of the concept of methods, and will break linting.
4. Use a factory pattern or object generator function. I'd rather avoid this, as it will add by far the most complexity to the code base.

What would be considered the most "Pythonic" way to achieve this behaviour? One of the above methods, or is there an obvious alternative I've missed?

Answer: 
I think you are over-complicating this issue.

if you don't have any important reason to change the method attribute (first option), I would go with just writing a nice if-else in `dynamic_method()` to call the other functions (3rd option) or if I really want to be fancy I would make a makeshift switch-case out of a `dict` like this:

```
def dynamic_method(self):
    return {
        <value to run foo1>: foo1,
        <value to run foo2>: foo2,
        <value to run foo3>: foo3
    }[self.method_variation](self)

def foo1(self):
    pass

def foo2(self):
    pass

def foo3(self):
    pass

```
I would rather go for option 3, since I find it cleaner, but it depends on how many implementation variations you need. Option 4 (use a factory) is good as well, but it will generate more code. On the other side, option 4 is by far more scalable and maintainable.

So, since you want to change the behaviour of the `dynamic_method()` within `__init__()`, you could do it like this:

```
class MyClass(object):
     def __init__(self, param=None):
         self.dynamic_method = {
             "a": self.dynamic_a,
             "b": self.dynamic_b,
             "c": self.dynamic_c}[param]

     def dynamic_a(self):
         print("a functionality")

     def dynamic_b(self):
         print("b functionality")

     def dynamic_c(self):
         print("c functionality")

>> m = MyClass("b")
>> m.dynamic_method()
b functionality

```