[Python-3000] PEP to change how the main module is delineated

Giovanni Bajo rasky at develer.com
Sat May 5 13:39:37 CEST 2007


On 24/04/2007 0.05, Guido van Rossum wrote:

>> This PEP is to change the ``if __name__ == "__main__": ...`` idiom to
>> ``if __name__ == sys.main: ...``  so that you at least have a chance
>> to execute module in a package that use relative imports.
>>
>> Ran this PEP past python-ideas.  Stopped the discussion there when too
>> many new ideas were being proposed.  =)  I have listed all of them in
>> the Rejected Ideas section, although if overwhelming support for one
>> comes forward the PEP can shift to one of them.
> 
> I'm -1 on this and on any other proposed twiddlings of the __main__
> machinery. The only use case seems to be running scripts that happen
> to be living inside a module's directory, which I've always seen as an
> antipattern. To make me change my mind you'd have to convince me that
> it isn't.

Sometimes, beginners get confused because of this. They start with a single 
module, it grows and grows, until they split it into another module. But if 
the two modules then import each other, there is an asymmetry because one is 
internally renamed to __main__. For instance:

==== a.py ====
class A:
    pass

if __name__ == "__main__":
    a = A()
    print A.__name__
    print a.__class__
    import b
    b.run(a)
===============

==== b.py ====
from a import A

def run(a):
    print A
    print a.__class__
    assert isinstance(a, A)  # FAIL!
==============

$ python a.py
A
__main__.A
a.A
__main__.A
Traceback (most recent call last):
   File "a.py", line 9, in ?
     b.run(a)
   File "E:\work\b.py", line 6, in run
     assert isinstance(a, A)  # FAIL!
AssertionError

I think this behaviour confuses many beginners, and it is unnatural for 
experts too. I've got bitten a few times in the past.

I still believe that it would be much easier to just support an explicit 
__main__ function:

==== a.py ====
class A:
    pass

def __main__():
    a = A()
    print A.__name__
    print a.__class__
    import b
    b.run(a)
===============

which is easier to read for beginners and let the main module keep its 
original name, thus not causinng these weird side-effects.
-- 
Giovanni Bajo



More information about the Python-3000 mailing list