FWIW, one of my intro students just yesterday asked about this:

Is there a way to call a function in a python file directly from the command line?

I have no idea what their programming background is, or why they expected that to be possible, but there you go -- at least one newbie expected it to be possible :-)

However: This was literally class number one -- I had not yet showed them the "if __name__ == '__main__':" idiom yet.

Also, I'm pretty sure this student's expectation was that there would not have to be anything special about the function (except maybe taking only string arguments?)  -- so it's probably not a good idea to try to solve that use case anyway.

But that was the first time I was ever asked that question -- and here it is on python-ideas -- quite a coincidence!

-CHB





On Tue, Oct 20, 2020 at 11:16 PM Paul Sokolovsky <pmiscml@gmail.com> wrote:
Hello,

On Wed, 21 Oct 2020 00:24:47 -0400
Michael Smith <michael@smith-li.com> wrote:

> On Tue, Oct 20, 2020 at 23:43 Guido van Rossum <guido@python.org>
> wrote:
>
> > The ‘if __name__…’ idiom makes one function special. Hm... So if the
> > module has that, will that main() still be called with your
> > proposal? I.e., is __name__ still ‘__main__’?
> > 
>
> Perhaps not. If __name__ were still '__main__' and calling the
> function implied importing the module, then anything in `if __name__
> == '__main__'` would still get run. I think that would be
> inconvenient for folks.

Alternative valuation is that your proposal is inconvenient to folks,
as it leaves too many gaps. Which, as it seems, you're eager to
bravely patch, but that does/will lead to only more confusion.

> I think __name__ should be the module name in the context of the
> module, and the function name in the context of the function, in this
> case.

__name__ is the name of the module. Or, as a special exception, it's
"__main__" for a module directly invoked as a script or via "-m"
switch.

There's no need to complicate it any further (it's already complicated
enough; my bet that half of Python users won't be able to formulate it
like above by heart).


Back to the original proposal, there's no general need to invoke
an arbitrary function in an arbitrary module. That just makes no sense,
as most functions depend on context.

If *you* need that, then, besides other options you mentioned in
your original mail, it's trivial to write a module which will do it for
you, like:

python -m my_super_invocator module:thunk


Actually, if you look on PyPI, I bet you'll find a few like that.

>
> On Tue, Oct 20, 2020 at 20:32 Michael Smith <michael@smith-li.com>
> wrote:
> > 
> >>
> >>
> >> On Tue, Oct 20, 2020 at 23:12 Guido van Rossum <guido@python.org>
> >> wrote:
> >>> On Tue, Oct 20, 2020 at 8:06 PM Michael Smith
> >>> <michael@smith-li.com> wrote:
> >>> 
> >>>> On Tue, Oct 20, 2020 at 10:19 PM Guido van Rossum
> >>>> <guido@python.org> wrote: 
> >>>> >
> >>>> > I think it would be a tad more convincing if there was a way
> >>>> > to pass 
> >>>> arguments too (even if just a list of strings). At the very
> >>>> least extra arguments should end up in sys.argv[1:].
> >>>>
> >>>> Could python -m 'module:thunk' have exactly the same behavior
> >>>> with respect to arguments as `python3.8 -m module` does today?
> >>>>
> >>>> ```
> >>>> $ cat bar.py
> >>>> import pprint, sys
> >>>>
> >>>> def thunk():
> >>>>     pprint.pprint(sys.argv)
> >>>>
> >>>> if __name__ == "__main__":
> >>>>     thunk()
> >>>>
> >>>> $ python3.8 -m bar -- -1 --two --three=3
> >>>> ['/Users/michael/bar.py', '--', '-1', '--two', '--three=3']
> >>>> ```
> >>>>
> >>>> So then with the same bar.py, `python -m bar:thunk -- -2 --three
> >>>> --four=4` would print `['/Users/michael/bar.py', '--', '-1',
> >>>> '--two', '--three=3']`. I like this better than my previous
> >>>> suggestion to shorthand python -c.
> >>>> 
> >>>
> >>> Actually it should print the same except for sys.argv[0]. (We
> >>> could argue about what sys.argv[0] should be.)
> >>>
> >>> 
> >>>> > Then again, presumably the function must be specially crafted
> >>>> > for 
> >>>> this usage. Why can't you just specially craft a module's main()?
> >>>>
> >>>> I'm not sure I know what you mean by "specially crafted", other
> >>>> than the function only needs not require any formal parameters.
> >>>> It doesn't need to be special-er than that. It can handle args
> >>>> via sys.argv, as you suggested. Most of the `main` functions I
> >>>> write today are just like that.
> >>>> 
> >>>
> >>> Okay, so this is just a way to choose an alternative main()
> >>> function.
> >>
> >> Am I missing something important here? What's special about naming
> >> a function "main"? Don't you still have to do something else to
> >> invoke it from the cli, such as calling it expressly in the module
> >> or pointing console entry points to it?
> >>
> >> ```
> >> $ echo 'def main(): print("hi")' > xyz.py
> >> $ python -m xyz
> >> <no output>
> >> $
> >> ```
> >>
> >> I'm kind of meh at this point, I'll leave it to the usual
> >> crowd. :-) 
> >>> 
> >>
> >> I appreciate the engagement you've given this already. :)
> >>
> >> -- 
> >>> --Guido van Rossum (python.org/~guido)
> >>> *Pronouns: he/him **(why is my pronoun here?)*
> >>> <http://feministing.com/2015/02/03/how-using-they-as-a-singular-pronoun-can-change-the-world/>
> >>> 
> >> -- 
> > --Guido (mobile)
> > 



--
Best regards,
 Paul                          mailto:pmiscml@gmail.com
_______________________________________________
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/7RFFX3PPJFT4HJY5ODBLZLYR2BDVFQRE/
Code of Conduct: http://python.org/psf/codeofconduct/


--
Christopher Barker, PhD

Python Language Consulting
  - Teaching
  - Scientific Software Development
  - Desktop GUI and Web Development
  - wxPython, numpy, scipy, Cython