In python, a variable can contain just about anything; that includes (but not limited to) a number, a string, a class object, or.. a function.
As you're probably already aware, the usage of (i.e. the things you can do with) a Python variable depends on whatever it happens to contain.
For example, you've probably seen that a variable containing a string will be able to be used with string manipulation, just as you would perform those same operations directly on a raw string.
What can you do with a variable containing a function? Answer - exactly the same thing as you can do with a function directly...
(... But remember that when copying a function into a variable, that function is identified by its name alone, without parenthesis; because the parenthesis will call the function and get its return value).
How do you assign a function to a variable? Answer - exactly the same way you assign any other kind of variable:
meow = say_hello # Note: no parenthesis.
meow() # Call the say_hello function, indirectly via 'meow'
How do you store a function-variable in a class? Answer - exactly the same way you store any other kind of variable in a class:
def __init__(self, callback):
self.callback = callback # just another variable...
self.callback() # "calling" the variable with parenthesis
# because it's expected to be a function.
meow = Foo(say_hello)
Try not to think about it too hard or get hung up on the fact that the variable contains a function rather than some other type of data/object. A variable is a variable no matter what it happens to contain.
Lastly, as you're probably already aware, a function is called using parenthesis with arguments. i.e.
If a function exists in a variable, then the function can be called by using function syntax with the variable. i.e.