stackkeeper
stackkeeper

Reputation: 121

Declaration functions in python after call

$ cat  declare_funcs.py
#!/usr/bin/python3

def declared_after():
        print("good declared after")

declared_after()

$ python3 declare_funcs.py
good declared after

Change call place:

$ cat  declare_funcs.py
#!/usr/bin/python3

declared_after()

def declared_after():
        print("good declared after")

$ python3 declare_funcs.py
Traceback (most recent call last):
  File "declare_funcs.py", line 4, in <module>
    declared_after()
NameError: name 'declared_after' is not defined

Is there way to declare only header of function like it was in C/C++?

For example:

#!/usr/bin/python3

def declared_after() # declaration about defined function 

declared_after()

def declared_after():
        print("good declared after")

I found this Declare function at end of file in Python

Any way there appear another function in the beginning like wrapper, and this wrapper must be called after declaration of wrapped function, this is not an exit. Is there more elegant true-python way?

Upvotes: 2

Views: 12013

Answers (4)

2rs2ts
2rs2ts

Reputation: 11066

You can't forward-declare functions in Python. It doesn't make a lot of sense to do so, because Python is dynamically typed. You could do something silly like this, and what would expect it to do?

foo = 3
foo()
def foo():
    print "bar"

Obviously, you are trying to __call__ the int object for 3. It's absolutely silly.

You ask if you can forward-declare like in C/C++. Well, you typically don't run C through an interpreter. However, although Python is compiled to bytecode, the python3 program is an interpreter.

Forward declaration in a compiled language makes sense because you are simply establishing a symbol and its type, and the compiler can run through the code several times to make sense of it. When you use an interpreter, however, you typically can't have that luxury, because you would have to run through the rest of the code to find the meaning of that forward declaration, and run through it again after having done that.

You can, of course, do something like this:

foo = lambda: None
foo()
def foo():
    print "bar"

But you instantiated foo nonetheless. Everything has to point to an actual, existing object in Python.

This doesn't apply to def or class statements, though. These create a function or class object, but they don't execute the code inside yet. So, you have time to instantiate things inside them before their code runs.

def foo():
    print bar()
# calling foo() won't work yet because you haven't defined bar()
def bar():
    return "bar"
# now it will work

The difference was that you simply created function objects with the variable names foo and bar representing them respectively. You can now refer to these objects by those variable names.

With regard to the way that Python is typically interpreted (in CPython) you should make sure that you execute no code in your modules unless they are being run as the main program or unless you want them to do something when being imported (a rare, but valid case). You should do the following:

  1. Put code meant to be executed into function and class definitions.
  2. Unless the code only makes sense to be executed in the main program, put it in another module.
  3. Use if __name__ == "__main__": to create a block of code which will only execute if the program is the main program.

In fact, you should do the third in all of your modules. You can simply write this at the bottom of every file which you don't want to be run as a main program:

if __name__ = "__main__":
    pass

This prevents anything from happening if the module is imported.

Upvotes: 5

poke
poke

Reputation: 388153

As zigg wrote, Python files are executed in order they are written from top to bottom, so even if you could “declare” the variable before, the actual function body would only get there after the function was called.

The usual way to solve this is to just have a main function where all your standard execution stuff happens:

def main ():
    # do stuff
    declared_after();

def declared_after():
    pass

main()

You can then also combine this with the __name__ == '__main__' idiom to make the function only execute when you are executing the module directly:

def main ():
    # do stuff
    declared_after();

def declared_after():
    pass

if __name__ == '__main__':
    main()

Upvotes: 0

Rushy Panchal
Rushy Panchal

Reputation: 17552

One thing you can do is enclose everything in a main function:

def main():
    declared_after()

def declared_after():
    print("good declared after")

main()

However, the point still stands that the function must be defined prior to calling. This only works because main is called AFTER declared_after is defined.

Upvotes: 4

Mattie B
Mattie B

Reputation: 21309

Python doesn't work that way. The def is executed in sequence, top-to-bottom, with the remainder of the file's contents. You cannot call something before it is defined as a callable (e.g. a function), and even if you had a stand-in callable, it would not contain the code you are looking for.

This, of course, doesn't mean the code isn't compiled before execution begins—in fact, it is. But it is when the def is executed that declared_after is actually assigned the code within the def block, and not before.

Any tricks you pull to sort-of achieve your desired effect must have the effect of delaying the call to declared_after() until after it is defined, for example, by enclosing it in another def block that is itself called later.

Upvotes: 4

Related Questions