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__
Actually it's not (defined after it's called). This script will do the following:
At that point dog
is already known in global scope and main
can call it.
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.
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
.