Question

I learned from a similar question on imports that one should not mix "operational code" and import (they should be at the top).

What is the consensus around defining functions in the middle of "operational code"?

I have a case where a function is used in just one place (it has to be a function) and having its definition close to that piece of code would make sense (all would be grouped together). It visually breaks the flow of the code, though.

Any advice from PEP? (I did not find anything relevant, as opposed to import)

EDIT: the apparent trend in the answers is that it is not a nice thing to do, but unlike the importcase mentioned above there are no definitive directives (PEP for instance)

Was it helpful?

Solution

All code in a python script or module (which is basically the same thing - the difference being how it is used) is "operational code" one way or another. The clean way to structure a script's code is to have everything in functions - what you name "operational code" being in a "main()" function - and just have a call to that "main" function if the module is used as a script, ie:

# mymoduleorscript.py
import something
from somewhere import somethingelse

def somefunc(arg1, arg2):
   # ...

def otherfunc(arga, argb):
   # ...

def main(*args):
   # "operational" code here
   return status_code # 0 if ok, anything else if error

# only call main if used as a script
if __name__ == "__main__":
     import sys
     sys.exit(main(*sys.argv[1:]))

Note that this is not a "in my opinion" answer, but the officially blessed OneTrueWay of doing things.

OTHER TIPS

Unless it's really necessary, i prefer to put all of it at the top of my script, since it makes finding them easier - more readable - and neater as well.

I think this starts to be pretty important if your code is going to be read by others, you don't want them to be confused when they want to see the functions, or how your code is operating.

Also, breaking down your program to smaller pieces, especially for long, long code is a good idea. When you have to deal with either part, you can do it quickly. So for me, the top is for declarations, and the bottom is for operational code. :)

I don't know why, but i feel like appending this here:

>>> import this
The Zen of Python, by Tim Peters

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
...

Well I am not sure if this is right or wrong as I am another newbie here. But I have implemented some thing like this in my code which will import in between the operational code.

code:

import os,importlib,

l  = os.listdir(os.getcwd())
x = [m.split('.')[0] for m in l if m.endswith('.py')] #  list all the py files in the direcory.

modules = []
for mod in x: 
    modules.append(importlib.import_module(mod)) # I am importing them using a for loop

I seriously dont know this is what you are looking for. But I will be glad if it can help you in any way... and I ll leave the commenting on best programming practices to the wizards here :)

I think the problem is that your operational code is too long, which leads to the fact that if you define that function before your operational code then it is too far from where it is called.

Having a very long piece of code is usually not a good idea, not only in Python. My suggestion is that find out some way to split your long piece of operational code into modules (functions or classes).

In my opinion keeping the functions out of the operational code is good for two reasons:

  1. It increases the readability of your program as in your operational code you can just call the function instead of stuffing the function between other expressions/statements. It makes the program look more cleaner as well.
  2. Stuffing the functions between your operational code spoils the structure of the program and makes the code look more complex

I could see that sometimes this might relate to "flat is better than nested". For example,

def dist(x, y):
    return abs(x - y)

for a, v in ls1:
    ls2.append(dist(a, b))

vs

for a, v in ls1:
    def dist(x, y):
        return abs(x - y)

    ls2.append(dist(a, b))

Personally I do sometimes mix functions and operational code. I don't see any specific PEP against it, but general considerations of code organization should still be taken into account.

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