Python Forum
placing module level statements into def - Printable Version

+- Python Forum (https://python-forum.io)
+-- Forum: Python Coding (https://python-forum.io/forum-7.html)
+--- Forum: General Coding Help (https://python-forum.io/forum-8.html)
+--- Thread: placing module level statements into def (/thread-3090.html)



placing module level statements into def - michaelcollier - Apr-28-2017

I have my own flowchart GUI for C++ that I'm extending to python and have a question about python statements that exist at module level i.e. they are outside of a def statement.

#module level statements, simple example
print(123)
The flowchart tool can handle statements that exist within def (because it can already handle C++ statements between braces{}), so I'm considering automatically wrapping module level statements into a pre-named def called "initialization".

#module initialization, wrapping commands into a def
def initialization():
    print(123)
initialization()
I'm not sure about the kind of issues I would have if I automatically wrapped such statements. Can anyone with python experience suggest any issues that may occur if I took this approach? I can then look at how the python is reverse engineered into the GUI and handle any such issues..

Thanks in advance


RE: placing module level statements into def - sparkz_alot - Apr-28-2017

We might need a clearer explanation, or at least expand it a bit.  The first thing is Python is not C++.  In your example, "print(123)" is not a "statement", it is a call to the builtin function "print()" with the argument of the integer "123".  If you are saying you would like to create a function that contains default values or performs the same thing every time it's called, then sure.  Unless you assign a variable(s), in which case they will only exist within "initialization" unless you use a "return" to send it to the outside world. I'm probably not explaining this well, but in my defense, I'm still on my first cup of coffee  Smile


RE: placing module level statements into def - michaelcollier - Apr-30-2017

Thanks sparkz_alot,

To clarify a bit more..

I only want the following statements at module level:

1. import
2. class
3. def
4. assignments ( a=xyz )

... Except for the __name__  /  __main__ test

5. if __name__ == "__main__":

 
What I definatley don't want at module level are things like:

6.  with
7.  while
8.  for
9.  pass
10. try
11. raise
12. function_call()
 
Can you see any technical reason why such a restriction would prevent doing things in python? I know it might not suit everyone...


RE: placing module level statements into def - ichabod801 - Apr-30-2017

I think you could work around just about anything with that restriction, but I think certain things might make the work around rather clunky. I try to follow that pattern, but I'm willing to break it when things get to clunky.

The first thing that comes to mind are complicated global constants. Sometimes you want a global constant that can't be created with a simple assignment. I will sometimes put that into a function, and assign the result of the function to the global constant, but that would seem to violate your rule #12.

The second thing that comes to mind is lengthy initialization. I had a poetry program that took a while to set up the word list, rhymes, and synonyms, so I would have a print statement at each point saying "Now initializing this part..." so the user knew why there was a delay.


RE: placing module level statements into def - michaelcollier - Apr-30-2017

A quick thought on notifying module loading, this could be centralized?

# module "import_notify.py"
import time

is_enabled = True
def notify ( a_str ):
    if is_enabled:
      print ( "Loading @: " + time.asctime() + " " + "'" + a_str + "'" )
    return
#place at top of every module
import import_notify
import_notify.notify ( __name__ )
Loading @: Sun Apr 30 14:07:27 2017 '__main__'
Loading @: Sun Apr 30 14:07:27 2017 'import_files'
Loading @: Sun Apr 30 14:07:27 2017 'more_files'
Loading @: Sun Apr 30 14:07:27 2017 'even_more_files'

(Apr-30-2017, 12:52 PM)ichabod801 Wrote: Sometimes you want a global constant that can't be created with a simple assignment. I will sometimes put that into a function, and assign the result of the function to the global constant, but that would seem to violate your rule #12.

Do you mean something like:

# "my_module.py"
def something_complex():
    return 1+3+4+5+6+7+8+9

global_const = something_complex()
That would be OK for my purposes, I just want to avoid calling something_complex() on its own.


RE: placing module level statements into def - ichabod801 - Apr-30-2017

I wouldn't centralize notifying, I rarely need to do it. But that is what I meant about using functions for complex constants.


RE: placing module level statements into def - volcano63 - May-01-2017

As far as complex constants go, I like to have string constants organized under a common object. A former colleague of mine found a recipe on SO using type. I tried to switch to Enums for that purpose, but occasionally it did not work well with os.path APIs - so I switched (back) to namedtuples

import time, re, collections
def make_enum(*enum_args, **enum_kwargs):
   _tokenizer = lambda s: re.sub('\W+', '_', s)
   enum_kwargs = {k.upper(): v for k, v in enum_kwargs.items()}

   enum_kwargs.update([(_tokenizer(s).upper(), s) for s in enum_args])
   return collections.namedtuple('_C_{:x}'.format(hash(time.time())), enum_kwargs.keys())(**enum_kwargs)

C = make_enum('true', 'false', sentence='This is long')
So that gives me nice object that helps me to avoid mismatched string constants bug
In [15]: vars(C)
Out[15]:
OrderedDict([('SENTENCE', 'This is long'),
             ('FALSE', 'false'),
             ('TRUE', 'true')])

In [16]: C.SENTENCE
Out[16]: 'This is long'

In [17]: C.FALSE
Out[17]: 'false'
This is to be usually called at the module level only. What good will it be for developer to have it tucked within a function? None at all.

In general, as the rules go - out of the second part, 10 and 12 excluded, they mostly follow common sense. You may need try for Python version adjustments; 12 makes no sense - especially since you may need to have (most common case)
sys.path.append()
I think that artificial restrictions on the language stifle productivity, creativity and job satisfaction. I have quit a job, where (misquoting my C++ instructor from long ago) Python-- was the standard Doh .

On the pro side,  they may win you Ig Nobel prize nomination  Big Grin .


RE: placing module level statements into def - Ofnuts - May-01-2017

(May-01-2017, 01:29 AM)volcano63 Wrote: On the pro side,  they may win you Ig Nobel prize nomination  Big Grin .

More like a Turding Award :)