I've found that the `if __name__ == "__main__"` idiom is unintuitive and feels unnecessary, and I'd like a cleaner way to write it. However, I don't like the idea of functions being "magically called." One of the things I don't like about C/C++ and so many other languages is the presence of a `main()` function that's implicitly called when you run the script. I don't think functions should be run without being called in the code. (TBH, I never did get far learning C++, so I'm no authority here.) I never liked how you can't import your package in its own __main__.py file (or maybe I'm missing something, packaging isn't my strong suit), so at first I thought, "Here's a way to move the script code into __init__.py!" `python -m package` could just call the main function in __init__.py! Everything could be so simple! However, after reading others' responses to the idea, I'm convinced that this wouldn't be good (i.e. there could be two copies of the module in memory). Keep __main__.py it is. Backwards compatibility isn't an issue. If your code needs to be compatible with previous versions of Python, don't use it. Problem solved. One compelling idea for me is the idea of automatic basic argument parsing. The main function could have command line arguments as arguments to it (like how `main` in other languages takes `argv` as an argument, but we could be specific here, by saying something like `def main(command, verbose=False)`), and the function that calls this main function purses arguments and passes them to the main function. We could use type hints and introspection to make this even more powerful. However, it could get very messy very quickly with options. I do think that this would be good motivation to do this, though. After all, using argparse can only be so much fun. My proposal is to make it look something like: run(main) Where `run` (a placeholder name for the proposed function) only executes if name equals main, and may do argument parsing and pass the arguments to `main`. -- Finn M. On Sat, Oct 2, 2021, 3:19 PM Anthony Baire <anthony.baire@irisa.fr> wrote:
why not evaluate the condition directly in the decorator, python 3.9 allows that ;-p
@lambda x: __name__ == "__main__" and x() def main(): ...
On 01/10/2021 21:35, Jonathan Crall wrote:
I was curious if / what sort of proposals have been considered for simplifying the pattern:
``` def main(): ...
if __name__ == "__main__": main() ```
I imagine this topic must have come up before, so I'd be interested in any relevant history.
But unless I'm missing something, it seems like adding some easier alternative to this cumbersome entrypoint syntax would be worth considering.
My motivation for writing this suggestion is in an attempt to stop a common anti-pattern, where instead of defining a `main` function (or a function by any other name) an simply calling that by adding the above two lines, a lot of Python users I work with will just start dumping their logic into the global scope of the module.
Needless to say, this can have consequences. If there was some default builtin, let's call it `__main__` for now (open to suggestions), that took a function as an argument and conditionally executed it if `__name__ == "__main__"` in the caller's scope, that would allow us to simplify the above boilerplate to a single line with no extra indentation:
``` def main(): ...
__main__(main) ```
In addition to being simpler, it would allow users to avoid the trap of adding logic that impacts the global scope. It would also save me some keystrokes, which I'm always grateful for.
Furthermore, it could be used as a decorator (and the use-case wouldn't be unreasonable!), and we all know how much new Python users love decorators when they find out about them.
``` @__main__ def main(): ... ```
Maybe having such a builtin would discourage globals and help new users get the use-decorators-everywhere bug out of their system.
-- -Dr. Jon Crall (him)
_______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-leave@python.orghttps://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/FKQS2N... Code of Conduct: http://python.org/psf/codeofconduct/
_______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-leave@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/4Y6JQJ... Code of Conduct: http://python.org/psf/codeofconduct/