[Python-ideas] Packages and Import

Ron Adam rrr at ronadam.com
Fri Feb 9 23:46:56 CET 2007


Josiah Carlson wrote:
> "Brett Cannon" <brett at python.org> wrote:
>> On 2/9/07, Ron Adam <rrr at ronadam.com> wrote:
>>> Brett Cannon wrote:
>>>> On 2/8/07, Ron Adam <rrr at ronadam.com> wrote:
>> [SNIP]
>>
>>>>> If you remove the "__main__" name, then you will still need to have some
>>>>> attribute for python to determine the same thing.
>>>> Why?  There is nothing saying we can't follow most other languages and
>>>> just have a reserved function name that gets executed if the module is
>>>> executed.
>>> Yes, but this is where python is different from other languages.  In a way,
>>> python's main *is* the whole module from the top to bottom.  And so the
>>> '__main__' name is referring to the whole module and not just a function in it.
>>>
>>> A more specific function would be needed to get the context right.  Maybe
>>> __script__(),  or __run__().
>>>
>>>
>>> Or if you want to be consistent with class's,  how about adding __call__() to
>>> modules?   Then the main body of the module effectively works the same way as it
>>> does in a class.  =)
>>>
>>>
>>> Hey, I think that has some cool possibilities, it makes modules callable in
>>> general.  So if I want to run a module's __call__(), AKA main() as you call it,
>>> after importing I would just do...
>>>
>>>     import module
>>>     module()
>>>
>>> And it would just work.  ;-)
>>>
>> I like this idea.  Makes it very obvious.  You just say "when a
>> specific module is specified at the command line it is called.  Could
>> even have it take possibly sys.argv[1:] (which I think was supposed to
>> turn into sys.args or sys.arg or something at some point).
>>
>> What do other people think?
> 
> I don't like it.  Much of my dislike comes from personal aesthetics, ....

Fair enough.  I have one aesthetic dislike myself, but its really minor. 
Currently you can always look at the bottom of files to see what they will do if 
you execute them.  With a main() function of any type, it may be someplace else. 
  But I can live with that if the name is always the same and doesn't change.


> .... but then there is a logical disconnect.  When an instance of a class is
> created, its __call__ method is not automatically called. By using the
> semantic of 'the __call__ function in the module namespace is
> automatically executed if the module is "run" from the command line', we
> are introducing a different instance creation semantic (an imported
> module is an instance of ModuleType).

I'm not sure I follow.  Importing a module would not call it's __call__() 
function.  As I've shown above it's an extra step.


Running a module isn't the same as importing one.  A lot of stuff goes on under 
the covers, so there really is no logical disconnect.  What it really does is 
just add one additional step to the "run from a command line" sequence of events.


> I think we should just stick with what has been proposed for *years*, a
> __main__ function that is automatically executed after the module has
> been imported if its __name__ == '__main__'.  Even better, anyone who
> wants to write code compatible with the updated syntax can include the
> following literal block at the end of their files...
> 
>     if __name__ == '__main__':
>         try:
>             __main__
>         except NameError:
>             pass
>         else:
>             try:
>                 __main__()
>             finally:
>                 try:
>                     from __future__ import disable_run
>                 except SyntaxError:
>                     #we are using an older Python
>                     pass
>                 else:
>                     #we are using a new Python, and
>                     #disabling automatic running succeeded
>                     pass
> 
> With such a semantic, current users of Python could include the above
> literal block and it would *just work*...then again, the new semantic
> wouldn't really be useful if people started using the above literal
> block.

That seems to be too much for some reason.



If __name__ returns the real name and a function ismain() is a new builtin, then 
these short one liners would work.


     #  Put at bottom of new programs so they work with older python too.

     if __name__ == '__main__': __call__()



     #  Makes old programs work with newer python.
     #  Add this above "if __name__=='__main__'".

     if hasattr(__builtins__, 'ismain') and ismain():  __name__ = '__main__'


Cheers,
    Ron








More information about the Python-ideas mailing list