An object is and isn't an instance of a class at the same time

Dave Angel d at davea.name
Mon Dec 10 01:48:23 CET 2012


On 12/09/2012 07:31 PM, Chris Angelico wrote:
> On Mon, Dec 10, 2012 at 10:34 AM, danielk <danielkleinad at gmail.com> wrote:
>> D:\home\python>python jtest.py
>> <class 'jukebox.jitem.Jitem'>
>> Traceback (most recent call last):
>>   File "jtest.py", line 4, in <module>
>>     executeResults = jc.execute(cmnd)
>>   File "D:\home\python\jukebox\jconnection.py", line 225, in execute
>>     raise TypeError("Command must be an instance of Jitem.")
>> TypeError: Command must be an instance of Jitem.
>>
>> How can it both get past isinstance() and still say it is the proper class?
> You're invoking it as __main__ and then also importing it. This gives
> you two instances of your module, with two separate classes that have
> the same name and (presumably) the same definition.
>
> If you use a separate driver script, you won't see this problem.
> Alternatively, simply stop checking isinstance and trust that, if
> something incompatible gets passed in, it'll throw an exception
> somewhere. That's usually enough.
>
>

Just to elaborate on ChrisA's comments.  You have a script which imports
a module, which in turn imports the script. That's called recursive
imports, and is a "BAD THING."

It can cause various problems, but in the particular case of importing
the top-level script, it can cause a very confusing one as you see
here.  There are two copies of any classes defined in the script, and
the system treats them as independent classes which only happen to have
the same name.  isInstance() is one place you might notice this, but
class static variables and even "global" variables in that module are
also candidates.  The real problem is that sometimes people treat the
symptom and never fix the underlying problem, the recursive import.

Whenever you have  "a imports b, which imports a," or you have  "a
imports b, which imports c, which imports a," you run the risk of
something getting initialized out of order, or worse getting initialized
twice.  You need to fix that, usually by factoring out some part which
is recursive, and moving it to an independent module which gets imported
by both the others.

You can also get into this type of confusion by importing a module by
two different names, for example if you import it from a directory in
one place, and from a package in another.

-- 

DaveA





More information about the Python-list mailing list