Question

Is it possible to forward-declare a function in Python? I want to sort a list using my own cmp function before it is declared.

print "\n".join([str(bla) for bla in sorted(mylist, cmp = cmp_configs)])

I've organized my code to put the definition of cmp_configs method after the invocation. It fails with this error:

NameError: name 'cmp_configs' is not defined

Is there any way to "declare" cmp_configs method before it's used? It would make my code look cleaner?

I assume that some people will be tempted to tell me that I should just reorganize my code so that I don't have this problem. However, there are cases when this is probably unavoidable, for instance when implementing some forms of recursion. If you don't like this example, assume that I have a case in which it's really necessary to forward declare a function.

Consider this case where forward-declaring a function would be necessary in Python:

def spam():
    if end_condition():
        return end_result()
    else:
        return eggs()

def eggs():
    if end_condition():
        return end_result()
    else:
        return spam()

Where end_condition and end_result have been previously defined.

Is the only solution to reorganize the code and always put definitions before invocations?

Was it helpful?

Solution

If you don't want to define a function before it's used, and defining it afterwards is impossible, what about defining it in some other module?

Technically you still define it first, but it's clean.

You could create a recursion like the following:

def foo():
    bar()

def bar():
    foo()

Python's functions are anonymous just like values are anonymous, yet they can be bound to a name.

In the above code, foo() does not call a function with the name foo, it calls a function that happens to be bound to the name foo at the point the call is made. It is possible to redefine foo somewhere else, and bar would then call the new function.

Your problem cannot be solved because it's like asking to get a variable which has not been declared.

OTHER TIPS

What you can do is to wrap the invocation into a function of its own.

So that

foo()

def foo():
    print "Hi!"

will break, but

def bar():
    foo()

def foo():
    print "Hi!"

bar()

will be working properly.

General rule in Python is not that function should be defined higher in the code (as in Pascal), but that it should be defined before its usage.

Hope that helps.

If you kick-start your script through the following:

if __name__=="__main__":
   main()

then you probably do not have to worry about things like "forward declaration". You see, the interpreter would go loading up all your functions and then start your main() function. Of course, make sure you have all the imports correct too ;-)

Come to think of it, I've never heard such a thing as "forward declaration" in python... but then again, I might be wrong ;-)

If the call to cmp_configs is inside its own function definition, you should be fine. I'll give an example.

def a():
  b()  # b() hasn't been defined yet, but that's fine because at this point, we're not
       # actually calling it. We're just defining what should happen when a() is called.

a()  # This call fails, because b() hasn't been defined yet, 
     # and thus trying to run a() fails.

def b():
  print "hi"

a()  # This call succeeds because everything has been defined.

In general, putting your code inside functions (such as main()) will resolve your problem; just call main() at the end of the file.

I apologize for reviving this thread, but there was a strategy not discussed here which may be applicable.

Using reflection it is possible to do something akin to forward declaration. For instance lets say you have a section of code that looks like this:

# We want to call a function called 'foo', but it hasn't been defined yet.
function_name = 'foo'
# Calling at this point would produce an error

# Here is the definition
def foo():
    bar()

# Note that at this point the function is defined
    # Time for some reflection...
globals()[function_name]()

So in this way we have determined what function we want to call before it is actually defined, effectively a forward declaration. In python the statement globals()[function_name]() is the same as foo() if function_name = 'foo' for the reasons discussed above, since python must lookup each function before calling it. If one were to use the timeit module to see how these two statements compare, they have the exact same computational cost.

Of course the example here is very useless, but if one were to have a complex structure which needed to execute a function, but must be declared before (or structurally it makes little sense to have it afterwards), one can just store a string and try to call the function later.

No, I don't believe there is any way to forward-declare a function in Python.

Imagine you are the Python interpreter. When you get to the line

print "\n".join([str(bla) for bla in sorted(mylist, cmp = cmp_configs)])

either you know what cmp_configs is or you don't. In order to proceed, you have to know cmp_configs. It doesn't matter if there is recursion.

There is no such thing in python like forward declaration. You just have to make sure that your function is declared before it is needed. Note that the body of a function isn't interpreted until the function is executed.

Consider the following example:

def a():
   b() # won't be resolved until a is invoked.

def b(): 
   print "hello"

a() # here b is already defined so this line won't fail.

You can think that a body of a function is just another script that will be interpreted once you call the function.

Sometimes an algorithm is easiest to understand top-down, starting with the overall structure and drilling down into the details.

You can do so without forward declarations:

def main():
  make_omelet()
  eat()

def make_omelet():
  break_eggs()
  whisk()
  fry()

def break_eggs():
  for egg in carton:
    break(egg)

# ...

main()

You can't forward-declare a function in Python. If you have logic executing before you've defined functions, you've probably got a problem anyways. Put your action in an if __name__ == '__main__' at the end of your script (by executing a function you name "main" if it's non-trivial) and your code will be more modular and you'll be able to use it as a module if you ever need to.

Also, replace that list comprehension with a generator express (i.e., print "\n".join(str(bla) for bla in sorted(mylist, cmp=cmp_configs)))

Also, don't use cmp, which is deprecated. Use key and provide a less-than function.

Import the file itself. Assuming the file is called test.py:

import test

if __name__=='__main__':
    test.func()
else:
    def func():
        print('Func worked')
# declare a fake function (prototype) with no body
def foo(): pass

def bar():
    # use the prototype however you see fit
    print(foo(), "world!")

# define the actual function (overwriting the prototype)
def foo():
    return "Hello,"

bar()

Output:

Hello, world!

"just reorganize my code so that I don't have this problem." Correct. Easy to do. Always works.

You can always provide the function prior to it's reference.

"However, there are cases when this is probably unavoidable, for instance when implementing some forms of recursion"

Can't see how that's even remotely possible. Please provide an example of a place where you cannot define the function prior to it's use.

Now wait a minute. When your module reaches the print statement in your example, before cmp_configs has been defined, what exactly is it that you expect it to do?

If your posting of a question using print is really trying to represent something like this:

fn = lambda mylist:"\n".join([str(bla)
                         for bla in sorted(mylist, cmp = cmp_configs)])

then there is no requirement to define cmp_configs before executing this statement, just define it later in the code and all will be well.

Now if you are trying to reference cmp_configs as a default value of an argument to the lambda, then this is a different story:

fn = lambda mylist,cmp_configs=cmp_configs : \
    "\n".join([str(bla) for bla in sorted(mylist, cmp = cmp_configs)])

Now you need a cmp_configs variable defined before you reach this line.

[EDIT - this next part turns out not to be correct, since the default argument value will get assigned when the function is compiled, and that value will be used even if you change the value of cmp_configs later.]

Fortunately, Python being so type-accommodating as it is, does not care what you define as cmp_configs, so you could just preface with this statement:

cmp_configs = None

And the compiler will be happy. Just be sure to declare the real cmp_configs before you ever invoke fn.

One way is to create a handler function. Define the handler early on, and put the handler below all the methods you need to call.

Then when you invoke the handler method to call your functions, they will always be available.

The handler could take an argument nameOfMethodToCall. Then uses a bunch of if statements to call the right method.

This would solve your issue.

def foo():
    print("foo")
    #take input
    nextAction=input('What would you like to do next?:')
    return nextAction

def bar():
    print("bar")
    nextAction=input('What would you like to do next?:')
    return nextAction

def handler(action):
    if(action=="foo"):
        nextAction = foo()
    elif(action=="bar"):
        nextAction = bar()
    else:
        print("You entered invalid input, defaulting to bar")
        nextAction = "bar"
    return nextAction

nextAction=input('What would you like to do next?:')

while 1:
    nextAction = handler(nextAction)

Yes, we can check this.

Input

print_lyrics() 
def print_lyrics():

    print("I'm a lumberjack, and I'm okay.")
    print("I sleep all night and I work all day.")

def repeat_lyrics():
    print_lyrics()
    print_lyrics()
repeat_lyrics()

Output

I'm a lumberjack, and I'm okay.
I sleep all night and I work all day.
I'm a lumberjack, and I'm okay.
I sleep all night and I work all day.
I'm a lumberjack, and I'm okay.
I sleep all night and I work all day.

As BJ Homer mentioned over above comments, A general rule in Python is not that function should be defined higher in the code (as in Pascal), but that it should be defined before its usage.

Hope that helps.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top