Reputation: 105197
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
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
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
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
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
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