After reading the following, I think I understand the value of wrapping even the simplest of scripts in a main() function.
Should I use a main() method in a simple Python script?
Why use def main()?
Should I define all my functions inside or outside main()?
Is there a right or wrong way? What are the advantages and disadvantages of both approaches?
I would discourage defining functions inside of main(), especially if you have multiple files in your Python script. Any function B defined inside of function A cannot be used by anything outside of function A, severely limiting its usability. Functions defined inside main() cannot be imported elsewhere, for example.
Defining functions inside of main() lets you easily override other functions you may have written elsewhere that have the same name, but the instances where this is really useful are few and far between, and you should not be doing it as a general practice. Overall there are many more reasons for defining functions outside of main() than there are for defining them inside, and if you're learning Python that's definitely how you should handle it.
If you define a function inside of the main function, you won't be able to use it from the outside. Here is an example:
def outer():
print "outer function"
def main():
def inner():
print "inner function"
inner()
if __name__ == "__main__":
main() # outputs: "inner function"
outer() # outputs: "outer function"
inner() # fails!
So main is just an entry point not usually a good place for lots of methods. Best practice would be to separate functionality among classes. It also makes it easier to manage in the future if changes need to be made. Hope this helps.
Hello and good question.
Just by "being use to" main() functions, many Python programmer with former experience in C++, Java, and C# love to use def name = "main" for of some sort. While "old school" programmers like this, Python is a very versitile, free form programming (actually it is a scripting language) what it does not need a main function.
If you were to make a basic calculator program, you can just make a function called "calc", and Python will be happy. I have made a GUI Vector Calculator w/o a "main" function, so there is Zero need.
def calc(x, y):
sum = x + y
return sum
Related
I have just been programming in python, and have been looking to just make simple programs to start getting a better understanding.
I am busy writing a rock paper scissors text game and to work out the games winner/looser etc I created a function. For a while I when I ran my program I kept getting an error when the function was called, it was that my function was not defined. My function was below my initial code.
However I for some reason moved my function to the top of my code under my global variable declarations, and now my function executes perfectly.
Why is this the case? is there a way I can have my functions below my main code but not get the error of my function being undefined. Would I just need to declare my function before and then call it later, if so, how would I declare an empty function?
I would love to understand so any help would be greatly appreciated.
Why is this the case?
Because that's the way Python works - all the code at the top-level of a module or script is executed sequentially, so functions are only defined after the def statement has been executed.
You have to understand that in Python everything is an object, including functions, classes etc, so the def statement is mostly a syntactic sugar that creates a function object (from the def block) and binds it to the function name, IOW a function is just another global variable in your module or script - and you wouldn't expect to be able to use a variable before you defined it, would you ?
is there a way I can have my functions below my main code but not get the error of my function being undefined.
Yes quite simply by putting your "main code" in a function and call this function at the end of the script:
import something
import another thing
def main():
bar = foo()
print("the answer is {}".format(bar))
def foo():
return 42
# this makes sure the main function will only be executed
# when using your .py file as a script, not when importing
# it as a module.
if __name__ == "__main__":
main()
Function has to be defined first before it is called.You have to define a function and afterwards function can be called anywhere in the program.
This is how Python works,in this all the things executes in a sequence.
I'm curious what the relative merits are of calling functions in a program using a decorator to create an ordered map of the functions, and iterating through that map, versus directly calling the functions in the order I want. Below are two examples that yield the same result:
PROCESS_MAP = {}
def register(call_order):
def decorator(process_func):
PROCESS_MAP[call_order] = process_func
return process_func
return decorator
#register(99)
def func3():
print 'last function'
#register(1)
def func0():
print 'first function'
#register(50)
def func1():
print 'middle function'
def main():
for func in sorted(PROCESS_MAP):
foo = PROCESS_MAP[func]
foo()
if __name__ == '__main__':
main()
This prints:
first function
middle function
last function
Is this any better than doing the following?
def func2():
print 'last function'
def func0():
print 'first function'
def func1():
print 'middle function'
def main():
func0()
func1()
func2()
if __name__ == '__main__':
main()
Some more questions:
More Pythonic?
More work than it's worth?
Does it open the door to too many issues if you don't properly assign the order correctly?
Are there more intelligent designs for calling functions in the right order?
I would prefer the second (non-decorated) approach in all situations I can think of. Explicitly naming the functions is direct, obvious, and clear. Consider asking the question "where is this function called from?" and how you might answer that in each case.
There is a possible bug in your decorator where it would silently drop a function that has the same call order number as a different function.
The first one will let you change order dynamically if you need and will also let you change the order with an external script much easier.
If your program's logic is clear and simple OR if you program will one day become more complex and the decorator will be irrelevant/will need to go under major changes in order to fit- use the second one.
You can read about more of the decorations common uses here:
What are some common uses for Python decorators?
But to conclude, I would say it really depends on your design and what is the programs purpose.
Furthermore, I would suggest, if choosing the first way, writing a better mechanism that will log the order, handle two function and more. Those improvements will maybe make the decorator worth it.
I say the second approach, unless you somehow wants to call a lot of functions and too lazy to type (and if you're actually doing this, there might be something wrong with your structure). Not only it is more readable and thus help minimize unnecessary errors, but it's also shorter.
PEAK Rules has some interesting utilities for this with #before, #after decorators and an interesting system for making rules to enforce certain behaviors.
A simpler mechanism would be to assign a 'weight' to each function and then sort them in weighted order - although this assumes a single array of functions. You can do a topological sort on a DAG to get a linear array of nodes if there is a hierarchy.
I learned that functions should perform a well-defined action and should be named according to what they do. For example, a function that adds its two arguments could be written:
def adder(arg1, arg2):
return arg1 + arg2
Here, adder has a well-defined role and its name says exactly what it does. Now, if a game loop was implemented as a function:
def mainloop(fps):
while True:
# DO STUFF
tick(fps)
would it still be right to say that the function is doing something and has a well-defined role? If so, what exactly are the advantages of implementing the loop as a function instead of leaving it in the global scope?
Due to an implementation detail, the same code in a function can run faster than when it is in the global namespace.
It would still be good form to have your loop outside of a function, there is nothing wrong with that. For one of my own pygame projects, I had to do that because otherwise there was scoping issues. An advantage of putting it into a function is that you could potentially access it from another python file:
from game import mainloop
mainloop(65)
I bring a few days working on python coming from Matlab and I have the next doubt:
I had a matlab program with a lot of functions defined at the end of my m-file. Matlab recognizes those functions even if I call them at the beginning and they are defined at the bottom of my code.
Now, with python, I don't know what is the best way to put the functions because python needs to know the definition of the functions before calling them.
I don't want to create a new file for each function.
I would like to put all functions together but I can't figure it out.
I hope you can help me.
Thx,
Another way you can have all the functions is to add a function that does everything you want it to do:
def main():
#do stuff
f()
g()
...
And add this to the end of the file:
if __name__ == '__main__':
main()
This will only execute if your file is the main file. If you import your file from another file, then it won't execute all the code in main().
You can put all the functions in a functions.py and include it in every document
import functions
then you can call a function by adding the prefix functions.
Actually python does not need you to declare functions in any particular order to have them called.
For example this works fine :
def a():
return b()
def b():
return 1
a()
This question already has answers here:
How do I forward-declare a function to avoid `NameError`s for functions defined later?
(17 answers)
Closed 8 months ago.
I use Python CGI. I cannot call a function before it is defined.
In Oracle PL/SQL there was this trick of "forward declaration": naming all the functions on top so the order of defining doesn't matter.
Is there such a trick in Python as well?
example:
def do_something(ds_parameter):
helper_function(ds_parameter)
....
def helper_function(hf_parameter):
....
def main():
do_something(my_value)
main()
David is right, my example is wrong.
What about:
<start of cgi-script>
def do_something(ds_parameter):
helper_function(ds_parameter)
....
def print_something():
do_something(my_value)
print_something()
def helper_function(hf_parameter):
....
def main()
....
main()
Can I "forward declare" the functions at the top of the script?
All functions must be defined before any are used.
However, the functions can be defined in any order, as long as all are defined before any executable code uses a function.
You don't need "forward declaration" because all declarations are completely independent of each other. As long as all declarations come before all executable code.
Are you having a problem? If so, please post the code that doesn't work.
In your example, print_something() is out of place.
The rule: All functions must be defined before any code that does real work
Therefore, put all the statements that do work last.
An even better illustration of your point would be:
def main():
print_something()
....
def do_something(ds_parameter):
helper_function(ds_parameter)
....
def print_something():
do_something(my_value)
def helper_function(hf_parameter):
....
main()
In other words, you can keep your definition of main() at the top, for editing convenience -- avoiding frequent scrolling, if most of the time is spent editing main.
Assuming you have some code snippet that calls your function main after it's been defined, then your example works as written. Because of how Python is interpreted, any functions that are called by the body of do_something do not need to be defined when the do_something function is defined.
The steps that Python will take while executing your code are as follows.
Define the function do_something.
Define the function helper_function.
Define the function main.
(Given my assumption above) Call main.
From main, call do_something.
From do_something, call helper_function.
The only time that Python cares that helper_function exists is when it gets to step six. You should be able to verify that Python makes it all the way to step six before raising an error when it tries to find helper_function so that it can call it.
I've never come across a case where "forward-function-definition" is necessary.. Can you not simply move print_something() to inside your main function..?
def do_something(ds_parameter):
helper_function(ds_parameter)
....
def print_something():
do_something(my_value)
def helper_function(hf_parameter):
....
def main()
print_something()
....
main()
Python doesn't care that helper_function() is defined after it's use on line 3 (in the do_something function)
I recommend using something like WinPDB and stepping through your code. It shows nicely how Python's parser/executor(?) works
def funB(d,c):
return funA(d,c)
print funB(2,3)
def funA(x,y):
return x+y
The above code will return Error. But, the following code is fine ...
def funB(d,c):
return funA(d,c)
def funA(x,y):
return x+y
print funB(2,3)
So, even though you must definitely define the function before any real work is done, it is possible to get away if you don't use the function explicitly. I think this is somewhat similar to prototyping in other languages.. .
For all the people, who despite bad practice want a workaround...
I had a similar problem and solved it like this:
import Configurations as this
'''Configurations.py'''
if __name__ == '__main__':
this.conf01()
'''Test conf'''
def conf01():
print ("working")
So I can change my targeted configuration at the top of the file. The trick is to import the file into itself.
Use multiprocessing module:
from multiprocessing import Process
p1 = Process(target=function_name, args=(arg1, arg2,))
p1.start()