Class changes in circular imports when __name__ == '__main__'

Arnaud Delobelle arnodel at googlemail.com
Sun Sep 5 23:18:25 CEST 2010


Spencer Pearson <speeze.pearson at gmail.com> writes:

> Hi! I'm writing a package with several files in it, and I've found
> that "isinstance" doesn't work the way I expect under certain
> circumstances.
>
> Short example: here are two files.
> # fileone.py
> import filetwo
>
> class AClass( object ):
>   pass
>
> if __name__ == '__main__':
>   a = AClass()
>   filetwo.is_aclass( a )
>
> # filetwo.py
>
> import fileone
>
> def is_aclass( a ):
>   print "The argument is", ("" if isinstance(a, fileone.AClass) else
> "not"), "an instance of fileone.AClass"
>
>
> If you run fileone.py, it will tell you that "The argument is not an
> instance of fileone.AClass", which seems strange to me, given that the
> fileone module is the one that CREATES the object with its own AClass
> class. And if you replace "if __name__ == '__main__'" with "def
> main()", start Python, import fileone, and call fileone.main(), it
> tells you that the argument IS an instance of AClass.
>
> So, the module's name change to __main__ when you run it on its own...
> well, it looks like it puts all of the things defined in fileone in
> the __main__ namespace INSTEAD of in the fileone module's namespace,
> and then when filetwo imports fileone, the class is created again,
> this time as fileone.AClass, and though it's identical in function to
> __main__.AClass, one "is not" the other.
>
> Is this kind of doubled-back 'isinstance' inherently sinful? I mean, I
> could solve this problem by giving all of my classes "classname"
> attributes or something, but maybe it's just a sign that I shouldn't
> have to do this in the first place.

The behaviour is normal.  I suppose you could do something like this
(untested):

# fileone.py

if __name__ == '__main__':
  from fileone import *
  
  a = AClass()
  filetwo.is_aclass( a )
  
  import sys; sys.exit()

import filetwo

class AClass( object ):
  pass

-- 
Arnaud



More information about the Python-list mailing list