5

I need some clear explanation and maybe an example of how frameworks like JavaFX, Tkinter etc. work.

Lets take Python's Tkinter. When I bind a button's action I just do

def callback():
    print "clicked!"

b = Button(text="click me", command=callback)

Somehow I give the callback function as a parameter to the Button class and it then triggers it when necessary.

But how can I write a class, which will run a method defined later? Could you please give me a short example?

  • If the method isn't defined until later, how exactly would you specify that that button should call that method? – Izkata Mar 27 '16 at 23:11
7

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:

def say_hello():
    print "Hello"

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 say_hello():
    print "Hello"

class Foo:
    def __init__(self, callback):
        self.callback = callback   # just another variable...

    def do_it():
        self.callback()   # "calling" the variable with parenthesis 
                          # because it's expected to be a function.

meow = Foo(say_hello)
meow.do_it()

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. say_hello("hello").

If a function exists in a variable, then the function can be called by using function syntax with the variable. i.e. my_little_callback().

8

Like many dynamically-typed scripting languages, in Python functions are first-class values, which means they can be passed into and returned from functions just like any other ordinary value. So the direct answer to your question is "you just do it, there's nothing stopping you".

def square(n):
    return n * n

def do_twice(func, arg):
    return func(func(arg))

print do_twice(square, 2) // 16

Since you mentioned JavaFX, in most traditional statically-typed languages functions are not automatically first-class values. C#, along with more recent versions of Java and C++, provide ways of defining functions that are first-class values when you need them. But for a long time the only way to pass around "callbacks" in these languages was to pass around objects which had the desired callbacks as methods. JavaFX appears to have a Callback class for this purpose.

  • 2
    In many traditional statically-typed imperative languages functions were / are more or less first-class values. You can reference and pass around functions in C++, C, Pascal, etc. OTOH Java and C# tried to make an object of everything, and elided standalone functions; now they are slowly reverting this decision which was not exactly wise. For instance, in Python everything is an object, and objects are built from functions (not the other way around). This approach could be applied to a statically-typed language, too. – 9000 Mar 28 '16 at 1:43
  • @9000 Could you clarify what you mean by objects are built from functions (not the other way around)? – Zev Spitz Mar 28 '16 at 20:49
  • 1
    @ZevSpitz: In Python, an object is basically a map of names to fields, and some fields are callable. Both classes and their instances have methods as wrappers around functions, with .im_func members pointing to "bare" function objects. This is because in Python you can define a standalone function, it's a normal practice. In Java (and anything JVM-based, AFAIK), you cannot; you have to have an object with a single (usually static) method, and syntactic sugar to represent it as a "standalone" function, hiding the object. This is "the other way around". – 9000 Mar 28 '16 at 21:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.