[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