[Tutor] Which is better Practice and why

Oscar Benjamin oscar.j.benjamin at gmail.com
Mon Oct 22 20:26:09 CEST 2012


On 22 October 2012 16:14, eryksun <eryksun at gmail.com> wrote:
> On Mon, Oct 22, 2012 at 9:35 AM, Oscar Benjamin
> <oscar.j.benjamin at gmail.com> wrote:
>>
>> It is also sometimes useful to define a number of scripts that are in
>> the same directory but share some code by importing one another. You
>> need the if __name__ =="__main__" block for this.
>>
>> The problem that Devin is referring to only happens in certain odd
>> situations where the script that you run ends up importing itself
>> (perhaps indirectly). I have never personally had that problem though.
>
> Just to clarify that I'm following you, would you count the following
> as a script importing itself 'indirectly'?

Yes.

> Assume two modules in the same directory, mod1.py and mod2.py, can
> both act as the main entry point, and both import each other (assume
> no circular import problem).

They both import each other. That is a circular import and it can
create problems. My advice for this issue is not "avoid importable
scripts" but rather "avoid circular imports" (a good idea anyway).

> Then if mod1.py runs as __main__ and
> imports mod2, and mod2.py imports mod1, there are 2 copies of the
> classes and functions defined in mod1.py. For example, there's
> __main__.MyError vs mod1.MyError.

I agree that this would be problematic. However, if mod1.py and
mod2.py both import each another then neither of them is really an
independent script. There is no reason why any common code should not
be moved into a third module to avoid the circular import.

I have used importable scripts many times and never had this problem
because I have never used them with circular imports. Typically the
action of running the module as a script provides a command line
interface that does some common but useful thing with the code in that
same module (rather than code imported from other modules).

An example from a recent project: I have a module that defines
functions for interacting with a particular database. It can be
imported by scripts that perform computations based on the contents of
the database. It can also be run as a script in which case it provides
a command line interface to query/export the contents of the database.
This particular module does not import any other modules within the
same project so it will never have the circular import problem. There
are other importable scripts that depend on the database module but
they also don't use circular imports.


Oscar


More information about the Tutor mailing list