user2131316
user2131316

Reputation: 3287

should function be defined before it is used in python?

should the functions be defined before it is used? but why the following code works:

def main():
    dog()

def dog():
    print("This is a dog.")

if __name__ == '__main__':
    main()

I mean the dog() is defined after it is called, how this works?

Upvotes: 4

Views: 6536

Answers (3)

Shashank
Shashank

Reputation: 13869

Code within the blocks of functions/methods does not execute before the functions are called. And the CPython language implementation (that's the most common one and the one you are probably using) does not do name-checking at compile time like languages such as C. Since it is primarily an interpreted language, it checks if names are available in the namespace dynamically at runtime.

Furthermore something you should know about Python is that code within classes is executed at the time of class creation, but code with in methods/functions is not. A def statement simply adds the name of the function to the namespace. It does not run any code within the function itself until the function is called.

Consider the following legal Python code.

class Something:
    def __init__(self):
        self.puppy = Dog()

class Dog:
    def __init__(self):
        pass

inst = Something()

This is perfectly legal because __init__ is not run before Dog class gets defined. But what if we moved that constructor above the creation of class Dog?

This code would complain about a NameError because Dog isn't defined yet!

class Something:
    def __init__(self):
        self.puppy = Dog()

inst = Something()

class Dog:
    def __init__(self):
        pass

One final example...

This code would complain about the same NameError.

class Something:
    my_puppy = Dog()
    def __init__(self):
        self.puppy = Dog()

class Dog:
    def __init__(self):
        pass

inst = Something()

This is because all of the code inside Something is immediately executed and at that point in the execution, the namespace/scope does not have access to the name Dog.

Upvotes: 6

Martijn Pieters
Martijn Pieters

Reputation: 1123970

The name dog is looked up as a global. References to globals do not need to be referring to anything defined until they are actually used. The function main() doesn't use dog until it is called.

If dog was not defined, calling main() would result in a NameError exception:

>>> def main():
...     return dog()
... 
>>> main()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in main
NameError: global name 'dog' is not defined
>>> def dog():
...     return 'Woof!'
... 
>>> main()
'Woof!'

Python doesn't really care what dog is. I can make it a class too, or something that is not callable even:

>>> class dog:
...     pass
... 
>>> main()
<__main__.dog instance at 0x10f7d3488>
>>> dog = 'Some string'
>>> main()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in main
TypeError: 'str' object is not callable

Because in the last example, dog is now bound to a string, the main function fails when trying to call it.

Upvotes: 8

viraptor
viraptor

Reputation: 34205

Actually it's not (defined after it's called). This script will do the following:

  • create function and assign it to "main"
  • create function and assign it to "dog"
  • call "main"

At that point dog is already known in global scope and main can call it.

Upvotes: 8

Related Questions