@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.me...@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-le...@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)
_______________________________________________
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@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/KRZDBEVTG2LMDLYHWUQFYL62FX7O6SWZ/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to