getting equal behavior for scripts and modules ?

Discussion in 'Python' started by Stef Mientki, Oct 11, 2009.

  1. Stef Mientki

    Stef Mientki Guest

    hello,

    I do agree that circular references should preferable be avoided.

    In languages like Delphi, you get an error message, trying to use
    circular references,
    but solving them in large programs with a lot of history can be very
    painful.

    Now I finally (after 2 years) knowing there's a difference between
    modules and scripts,
    I want to guarantee that I always get the same functional behavior.

    I found 2 solutions to realize the above.

    === solution 1 ===
    Inserting a launcher into the IDE,
    so instead of running the application as a script,
    the file will always be executed as a module.
    """
    == Launcher ==
    instead of
    if __name__ == '__main__' :
    define a function
    def main () :
    and start this Launcher with the first parameter being the name of the
    module
    Launcher <module to be tested> <other arguments>
    """

    import sys
    __My_Main_Application = __import__ ( sys.argv[1] )

    if 'main' in dir ( __My_Main_Application ) :
    __My_Main_Application.main ()



    === solution 2 ===
    Prevent execution of the code in this file if the file is ran as a script.
    if __name__=='__main__':
    import os, sys

    # determine the name of myself
    a = sys._getframe().f_code.co_filename
    X = os.path.splitext ( os.path.split(a)[1] ) [0]

    #import myself as 'ME'
    ME = __import__ ( X )

    # run some code in myself
    ME.functional_code ()

    # prevent that the code below is executed,
    # ( for the second time )
    # if this file is used as a script
    sys.exit()

    print 'One time import code'
    def functional_code () :
    print 'Functional Code'



    any comment ?
    thanks,
    Stef Mientki
     
    Stef Mientki, Oct 11, 2009
    #1
    1. Advertising

  2. On Sun, 11 Oct 2009 19:50:31 +0200, Stef Mientki wrote:

    > Now I finally (after 2 years) knowing there's a difference between
    > modules and scripts,
    > I want to guarantee that I always get the same functional behavior.


    You are confused. Scripts *are* modules. What makes a script a script is
    that it is executed from the shell:

    $ python ~/scripts/helloworld.py
    Hello World.
    $

    The difference isn't between files which *are* scripts and files which
    *are* modules, but between modules which do something useful when *run as
    a script* versus modules which don't. Recent versions of Python even
    include a switch -m that searches the sys.path for the named module and
    runs the module's .py file as a script.

    You don't get the same behaviour between *running* a module and
    *importing* a module because they do different thing. When you say
    "import module" inside the Python environment, the module goes through
    the import machine. When you say "python script.py" in the shell, it
    doesn't.

    When you import a module, Python looks to see if it has already been
    imported, and if it has, it returns the module object in the cache. If
    not, then it does a whole lot of magic which includes executing the code
    inside the module. This means that modules get executed only once in any
    session (unless you remove it from the cache).

    When you run a module as a script from the shell, it doesn't go through
    the import machinery, it doesn't get looked up in the cache, and it gets
    executed every time.

    The consequence of this is that if you run a module as a script, it gets
    executed. If, in the process of being executed, it imports itself
    (directly or indirectly), the import machinery has to run it again. Hence
    the module gets executed twice.


    > I found 2 solutions to realize the above.


    Over-engineered overly-complicated non-solution to a non-problem.

    The simplest solution is as follows: code that must always be executed
    goes in the body of the module. Code that *only* gets executed when
    running as a script goes under a test:



    if __name__ == '__main__':
    # running as a script
    # code goes here
    pass

    That code will *only* run when running as a script, and not when you
    import the module. Everything outside such a test will always run. If you
    don't want that distinction, then don't use such a test.



    --
    Steven
     
    Steven D'Aprano, Oct 11, 2009
    #2
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Paul F. Johnson
    Replies:
    12
    Views:
    680
    Mark Parnell
    Oct 25, 2004
  2. Andreas Leitgeb
    Replies:
    5
    Views:
    210
    Andreas Leitgeb
    Aug 3, 2012
  3. Andreas Leitgeb
    Replies:
    5
    Views:
    191
    Andreas Leitgeb
    Aug 3, 2012
  4. Andreas Leitgeb
    Replies:
    2
    Views:
    121
    markspace
    Aug 3, 2012
  5. Andreas Leitgeb
    Replies:
    2
    Views:
    147
    markspace
    Aug 4, 2012
Loading...

Share This Page