devoured elysium
devoured elysium

Reputation: 105197

Is it possible to use functions before declaring their body in python?

Is there any way to make possible to use functions in your file before you actually declare their body?

The following code doesn't seem to work:

abc = myFunction

def myFunction():
    print "123"

Thanks

Upvotes: 17

Views: 14505

Answers (5)

John Millikin
John Millikin

Reputation: 200916

You can't use the myFunction variable before it's assigned. Your example code is similar to:

def myFunction():
    print abc
    abc = 123

To do what you want, either re-arrange the order:

def myFunction():
    print "123"

abc = myFunction

Or declare abc as just a proxy:

# Style 1
abc = lambda: myFunction()

# Style 2
def abc():
    return myFunction()

def myFunction():
    print "123"

If your function takes parameters, use *args and **kwargs:

# Style 1
abc = lambda *args, **kwargs: myFunction(*args, **kwargs)

# Style 2
def abc(*args, **kwargs):
    return myFunction(*args, **kwargs)

def myFunction(x):
    print x

Upvotes: 22

Jim Dennis
Jim Dennis

Reputation: 17510

Python will raise a NameError as it encounters any reference to any name (token that's a valid variable/class/function/object name) for which there was no previous binding.

The Python interpreter executes the source code of a file as it reads it. Thus def foo(): is actually statement which defines foo() as the code is being loaded.

It's easy to think that forward references are supported. Consider this:

def foo():
    return abc

abc="FooBar, Dude"

print foo()

... and you'll see that it can be run without issues. It's best to think of the definition of foo() as being quoted. The contents aren't evaluated until the function is invoked. So the NameError isn't raised (so long as some value has been bound to the name "abc" before the call to the function.

Notice that some of these semantics are sufficiently different than those from languages like Java, C/C++, and Perl that Pythonistas often prefer to use slightly different terminology. Variables and such are called "names" and the process of associating those with values (or, more generally, objects) is referred to as "binding." So instead of "assigning values to variables" you are "binding objects to names."

Informally names, especially for simple numeric or string objects, are called "variables" and statements such as x='foo' are referred to as assignments. The semantics are usually similar enough that we won't care.

Upvotes: 1

jbochi
jbochi

Reputation: 29654

You can declare an empty function, use it to set attributes or anything like this, and then modify its code later.

def myFunction():
    pass

myFunction.foo = 'bar'

def makeFunction(obj):
    def myFunction():
        print "123"

    f = myFunction
    for attr in dir(obj):
        if attr not in dir(f):
            setattr(f, attr, getattr(obj, attr))

    return f


myFunction = makeFunction(myFunction)
myFunction()
print myFunction.foo

Upvotes: 1

Greg Hewgill
Greg Hewgill

Reputation: 994191

You can declare functions that use forward declarations, but Python executes the code in your source from top to bottom. So, this would compile and run:

def foo():
    print "in foo"
    bar()

def bar():
    print "in bar"
    foo()

foo()

(except it would cause a stack overflow at runtime, of course). In your example, Python is executing the line

abc = myFunction

before myFunction is defined as anything. You could think of this in terms of typing your source code interactively into the interpreter. When you type in your assignment, you wouldn't have even typed in the definition of myFunction yet, so Python wouldn't be able to refer to it.

Another way to look at this might be the following:

>>> myFunction = "hello"
>>> abc = myFunction
>>> def myFunction():
...     print "there"
... 
>>> abc
'hello'
>>> myFunction
<function myFunction at 0x63270>
>>> myFunction()
there

As you can see, the definition of the myFunction function just changes the binding of the symbol myFunction to a function object.

Upvotes: 13

jldupont
jldupont

Reputation: 96826

short answer is no.

In Python, statements are evaluated along as they are parsed - myFunction wasn't parsed so Python doesn't know about it.

Upvotes: 1

Related Questions