18

Is there a shorter form of this?

if __name__ == '__main__':

It is pretty tedious to write, and also doesn't look very nice in my opinion :)

gak
  • 32,061
  • 28
  • 119
  • 154
  • 3
    "Tedious to write" - but at most once per module, usually less often. "doesn't look very nice" - yeah, but you'll survive it. –  Jan 23 '11 at 22:42
  • 3
    I've survived with it for years, delnan ;) – gak Jan 23 '11 at 22:47
  • I came here expecting an IDE specific solution. The programming language requires it, but even then a good IDE could still make it much easier to include (the writing is the tedious part so a one button or one keyboard shortcut solution would be fine). – NoDataDumpNoContribution Feb 10 '23 at 07:46

8 Answers8

13

PEP299 proposed a solution to this wart, namely having a special function name __main__. It was rejected, partly because:

Guido pronounced that he doesn't like the idea anyway as it's "not worth the change (in docs, user habits, etc.) and there's nothing particularly broken."

http://www.python.org/dev/peps/pep-0299/

So the ugliness will stay, at least as long as Guido's the BDFL.

Matt Curtis
  • 23,168
  • 8
  • 60
  • 63
9

Basically every python programmer does that. So simply live with it. ;)

Besides that you could omit it completely if your script is always meant to be run as an application and not imported as a module - but you are encouraged to use it anyway, even if it's not really necessary.

ThiefMaster
  • 310,957
  • 84
  • 592
  • 636
  • 9
    (I'm amused by +6 for an answer that doesn't actually give an answer to the question.) – Glenn Maynard Jan 23 '11 at 22:51
  • 1
    Maybe I should start a PEP :) – gak Jan 23 '11 at 22:52
  • 3
    @Gerald: see PEP299 (and my answer), it looks like we're stuck with this. (A shame for a language which is otherwise so clean that, on day 1, a new Python programmer gets exposed to an implementation detail which violates the first line of "The Zen of Python": "Beautiful is better than ugly") – Matt Curtis Jan 27 '11 at 06:51
8

After asking this question, I decided to make a solution to it:

from automain import *  # will only import the automain decorator

@automain
def mymain():
    print 'this is our main function'

The blog post explains it, and the code is on github and can be easy_installed:

easy_install automain
gak
  • 32,061
  • 28
  • 119
  • 154
  • 6
    Although definitely a neat Python trick, the complication added by this module makes it less useful. Code using this module will have any reader thereof going "wtf!?", expecting to find `if __name__ == '__main__':` and even the single imported decorated is arguably too great a sacrifice. – Walter Jan 25 '11 at 08:01
  • 2
    ...isn't this almost the same length? In the fairest possible way of counting, it's about 3 characters shorter. `from automain import * @automain` vs `if __name__ == "__main__": mymain()` – dbr Jan 25 '11 at 12:03
4

It's definitely a wart in the language, as is anything that becomes boilerplate and gets copied and pasted from file to file. There's no shorthand for it.

As warts and boilerplate go, though, at least it's minor.

Glenn Maynard
  • 55,829
  • 10
  • 121
  • 131
3

Shorter, if you count lines:

__name__ == '__main__' and main()
Prof. Falken
  • 24,226
  • 19
  • 100
  • 173
3

You mean shorter like if'__main__'==__name__: ?

Kabie
  • 10,489
  • 1
  • 38
  • 45
1

No, sorry, there is not. It doesn't look great, but it's what we've got.

payne
  • 13,833
  • 5
  • 42
  • 49
0

It is pretty tedious to write, and also doesn't look very nice in my opinion :)

My perfectionism also finds Python mains a tad ugly. So, I searched for solutions and finally used the following code.

Copy / pasted code :

# main_utils.py
import inspect
from types import FrameType
from typing import cast


def is_caller_main() -> bool:
    # See https://stackoverflow.com/a/57712700/
    caller_frame = cast(FrameType, cast(FrameType, inspect.currentframe()).f_back)
    caller_script_name = caller_frame.f_locals['__name__']

    return caller_script_name == '__main__'
#!/usr/bin/env python3

# test.py
# Use case

import main_utils


if main_utils.is_caller_main():
    print('MAIN')
else:
    print('NOT MAIN')

Source on GitHub Gist :

<script src="https://gist.github.com/benoit-dubreuil/fd3769be002280f3a22315d58d9976a4.js"></script>
Benoît Dubreuil
  • 650
  • 1
  • 11
  • 27