Skip to content

Instantly share code, notes, and snippets.

@carlsmith
Last active December 8, 2022 22:43
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save carlsmith/800cbe3e11f630ac8aa0 to your computer and use it in GitHub Desktop.
Save carlsmith/800cbe3e11f630ac8aa0 to your computer and use it in GitHub Desktop.
Main function decorator (for Python 2 and 3).
import inspect
def main(function):
locale = inspect.stack()[1][0].f_locals
module = locale.get("__name__", None)
if module == "__main__":
locale[function.__name__] = function
function()
return function
@carlsmith
Copy link
Author

carlsmith commented Feb 13, 2015

Features

Any functions decorated by main are automatically invoked if they are in a top-level script, else the decorator does nothing.

  • You can decorate more than one function.
  • More than one decorated function can be in the same file.
  • You can call the decorated function recursively.
  • Decorated functions can also be called like normal functions.

The idea was taken from automain by Gerald Kaszuba. It's been tweaked to allow the decorated function to be called recursively and repeatedly.

Use

First, import the decorator:

from automain import main

If this code is in the top level script, the function will be invoked automatically:

@main
def f(): print("hello world")

The decorator works with recursive functions:

@main
def f(n=3):
    print(n)
    if n: f(n - 1)

You can call decorated functions normally:

f(10)

@quassy
Copy link

quassy commented Jul 24, 2020

Is this still working with Python 3.8? I tried to get it running but it seemed to have no effect.

@carlsmith
Copy link
Author

I haven't used it for years to be honest. I tested it before posting it, but that was ages ago.

@TaurusEight
Copy link

The following modifications work fine for me under 3.10.5

from inspect import stack

def automain( func ) :
  locale = stack()[ 1 ].frame.f_locals
  module = locale.get( '__name__', None )
  if module == '__main__' :
    locale[ func.__name__ ] = func
    func()
  return func

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment