@Marc-Andre 

One of the motivations of this proposal is to incentivize writing code in a local scope, rather than a global one. People in this thread have made the argument "Python is a scripting language, so it should do that". Ok, fine. Yes `print('hello world')` is more idiomatic than the one inside of a function, but any real work done in Python quickly discards that global simplicity.

Variable assignment in a global scope is slower than the equivalent code in a local scope, due to the STORE_FAST bytecode being used inside a function and STORE_NAME being used in the global scope:  
https://stackoverflow.com/questions/11241523/why-does-python-code-run-faster-in-a-function

And it is true that this isn't a huge performance hit, and it is entirely avoidable by simply adding the 

```
def main():
    ...

if __name__ == '__main__':
    main()
```

boilerplate yourself, but it feels inelegant to me. I suppose it is a subtle reminder that Python is a scripting language, and we are coercing it into a library. So I can understand that argument.


One of the motivations for me posting this was a several students I was working with were putting all of their logic in the `if __name__ == '__main__'` block, defining global variables in them, and then relying on those global variable existing in other places in the code. This did what they expected when they were running their code as a script, but when I tried to import it as a module, I immediately encountered errors. My thought is that these errors would have been more obvious to the students if they were writing their logic (context is training a neural network) in a main function, rather than in the global scope.


@Christopher Barker

> The if __name__ block is only required for a Python file to be both a module and a script. 
> That’s actually a pretty uncommon thing— if it’s a module to be imported by other modules, then 

I suppose I do an uncommon thing fairly often. I work with neural networks and I generally construct a package with a pkg/fit.py pkg/predit.py and pkg/evaluate.py which all operate as both a module and a script. I'll run `python -m pkg.fit [args]` to train a network but I'll also `from pkg import fit`, especially when testing. I think if you are testing an executable module you almost always want to have part of it be importable so it can be unit tested. And I think the natural argument against that here, is, well why don't you put that in a `__main__.py`? To which my response is that `pkg` has multiple entry points, so that would require some sort of modal boilerplate, which is useful in many cases and I have done it, but it works against the simplicity of the case where it makes intuitive sense that the package module should be accessible as a module and a library.

Retrospectively, I would agree that this is probably uncommon, but if nothing else comes out of this discussion, I would want to encourage Python users to write Python files as both modules and executables more often. Having lots of entry points can be handy, and makes a lot of sense in many cases (e.g. whenever you have a main module with more than one function, it almost always makes sense to be able to import it to unit test the components). I would also encourage reserving the "__main__.py" file to be "the one true" entrypoint, or at least the primary public facing entrypoint. I find this pattern strikes a nice balance between having lots of entry points (which is good for people familiar with the code base) and having one obvious entrypoint for people learning the codebase. 

On Sun, Oct 3, 2021 at 10:20 AM David Mertz, Ph.D. <david.mertz@gmail.com> wrote:
On Sun, Oct 3, 2021, 1:46 AM Christopher Barker 
The if __name__ block is only required for a Python file to be both a module and a script. 
That’s actually a pretty uncommon thing— if it’s a module to be imported by other modules, then it probably should be part of a package, and if the functionality needs to be made available as a script, there can be another module just for that.

I think all the slightly different boilerplate forms suggested are needless. So on the main topic, -1.

But as a note, I usually put a __name__=='__main__' block at the foot of my library code.

The few functions in this particular file presumably do something useful, and hopefully composable. Why not allow command-line users to do just that one thing by itself? Sure, the predominant use is within a library, but being able to try out this functionality usually helps my development, and is sometimes useful to have around and composable in bash.
_______________________________________________
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/6XGPJH57YY4N2AC6P4VY67VNYPINZKQD/
Code of Conduct: http://python.org/psf/codeofconduct/


--
-Dr. Jon Crall (him)