Arafat Khan
Arafat Khan

Reputation: 857

How are we able to call functions before they are defined in Python?

In Python functional programming this code is valid and runs as expected:

def increment_5(num):
    number = 5
    number += num
    disp_result(num)

def disp_result(num):
    print(f"5 was increased by {num}")

increment_5(6) # -> 5 was increased by 6

I have created the disp_result() function after calling it. I have seen in other people's code (and I write in this way too) that they call functions after defining them and I believe this is the convention and good practice. But, as shown, we can also call a certain function before actually defining it. In OOP too, I can call a class method using self.certain_method() before acutally defining this method. So how is it achieved and is it something that happens in Python only?

I understand this question could have been asked before. If such, please know that I was unable to find it and linking to it would be helpful too.

Upvotes: 6

Views: 5622

Answers (4)

Klaws
Klaws

Reputation: 153

Python uses late binding. When you define increment_5(), Python just records that you want to call another function with the name "disp_result". Python doesn't check whether that function exists at this time, only when the actual call to "something named disp_result" is executed. And Python doesn't even know which "disp_result" is the correct one.

Let's have some fun.

def disp_result(num):
    print(f"5 was increased by {num}!!!!!")

def increment_5(num):
    number = 5
    number += num
    disp_result(num)

increment_5(6) # -> 5 was increased by 6

def disp_result(num):
    print(f"5 was increased by {num}?????")

increment_5(6) # -> 5 was increased by 6

Result:

5 was increased by 6!!!!!
5 was increased by 6?????

Note that Python defines functions at run time. def is not an instruction to a loader/compiler, it is actually a run time function which defines (or redefines) a function when the execution flow reaches that point. That also makes it possible to conditionally define functions:

a = 1

if a == 1:
    def f():
        print("I'm f()")
else:
    def f():
        print("I'm f(), too")

f()

Result:

I'm f()

Note that these examples are not meant to be examples for good and readable code.

Late binding (sometimes called "dynamic dispatch") is a feature of many object-oriented languages. Python just supports this for procedural programming as well.

Upvotes: 0

timgeb
timgeb

Reputation: 78770

As opposed to classes, function bodies are not executed without explicitly calling the function. Follow along:

>>> class A:
...     print('hello')
...     
hello
>>> def f():
...     print('hello')
...    
>>> # <nothing happened>

Since Python does not execute the function body until you call that function, you can populate the scopes where that function might look for specific names after defining it.

Upvotes: 3

wjandrea
wjandrea

Reputation: 33127

You can't call a function before it's defined. disp_result isn't called until increment_5 is called.

For example, this will fail:

def increment_5(num):
    number = 5
    number += num
    disp_result(num)

increment_5(6)  # -> NameError: name 'disp_result' is not defined

def disp_result(num):
    print(f"5 was increased by {num}")

Upvotes: 8

alani
alani

Reputation: 13079

The reason why code such as this works:

class Foo():

    def method1(self):
        self.method2()

    def method2(self):
        print("hello")

f = Foo()
f.method1()

is that the variable self.method2 inside Foo.method1 is only evaluated (and the function to which it points only gets called) at the time that the code inside Foo.method1 is actually executed, not while it is being defined.

Before class Foo can be instantiated, the class definition must first have completed (i.e. the class object must have been created and it must have been populated with all of its methods). Therefore at the time when the instance f exists and f.method1() (or equivalently, Foo.method1(f)) is called, the instance object (passed to the method via its self argument) already has a property method2 inherited from the class, which has by that time been fully populated.

It therefore does not matter in which order methods are declared within a class.

This is a completely different situation from trying to call a function before it has been defined.

Upvotes: 4

Related Questions