473,387 Members | 1,749 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,387 software developers and data experts.

bug with isinstance() ?

Mac
Under certain circumstances isinstance() seems to return incorrect
value for me. I'm using Python 2.3 (latest from Debian's unstable).
Here's a sample program... the multi-module nature of the code is key.
=== test.py ===

class Foo:
pass

def test():
from test2 import make_me_a_foo
foo = make_me_a_foo()
if isinstance(foo, Foo):
print "is a Foo"
else:
print "is NOT a Foo!"

if __name__ == "__main__":
test()
=== test2.py ===

from test import Foo

def make_me_a_foo():
return Foo()
--8<--

When I run "python test.py", I get "is NOT a Foo!", when the object
clearly IS a Foo! Am I missing something, or is this a bug?

Jul 19 '05 #1
7 1796
Mac a écrit :
Under certain circumstances isinstance() seems to return incorrect
value for me. I'm using Python 2.3 (latest from Debian's unstable).
Here's a sample program... the multi-module nature of the code is key.
=== test.py ===

class Foo:
pass

def test():
from test2 import make_me_a_foo
foo = make_me_a_foo()
if isinstance(foo, Foo):
print "is a Foo"
else:
print "is NOT a Foo!"

if __name__ == "__main__":
test()
=== test2.py ===

from test import Foo

def make_me_a_foo():
return Foo()
--8<--

When I run "python test.py", I get "is NOT a Foo!", when the object
clearly IS a Foo! Am I missing something,
Yes
or is this a bug?

Nope

try adding:
print foo.__class__

after the second line of your test() function.

Jul 19 '05 #2

"Mac" <id******************@yahoo.com> wrote in message
news:11**********************@g14g2000cwa.googlegr oups.com...
Under certain circumstances isinstance() seems to return incorrect
value for me. I'm using Python 2.3 (latest from Debian's unstable).
Here's a sample program... the multi-module nature of the code is key.
The key, which my debug addition below should help you see, is a
consequence of the mutually recursive definitions of the two modules, with
one of them also being the main module. This is a recipe for confusing
results that is best avoided. But I believe you could also get the same
confusing result with one file that imported itself directly rather than
indirectly via a second file.
=== test.py ===

class Foo:
pass def test():
from test2 import make_me_a_foo
foo = make_me_a_foo()
Try adding
print id(foo.__class__), foo.__class__
print id(Foo), Foo
if isinstance(foo, Foo):
print "is a Foo"
else:
print "is NOT a Foo!"

if __name__ == "__main__":
test() === test2.py ===

from test import Foo

def make_me_a_foo():
return Foo() When I run "python test.py", I get "is NOT a Foo!", when the object
clearly IS a Foo! Am I missing something
Yes, the ambiguity of Foo, which the print statements should reveal.
Deriving Foo from object to make it newstyle should give similar behavior.
or is this a bug?


Pretty sure not. It is hard to go wrong comparing ids for equality.

Terry J. Reedy

Jul 19 '05 #3
Mac
I see, interesting. OK, I understand that recursive importing can be
problematic (having to "hide" the test2 import should have been a tip
off; it's just that in my original app this relationship is not as
clear), but what is the lesson I should take away from this? I mean, I
was under the impression that "once a Foo, always a Foo", while from
the above I'm starting to see that a single class definition can give
rise to a multiple number of classes, and that the classes are
parametrized by the module they come from (I guess that makes sense...
else class names would have to be unique throughout all the source for
a single program)... I guess the problem is I'm thinking of "classes"
as these abstract concepts, sort of like Platonian "forms", whereas I
should be thinking of classes as "class objects", object instances,
each coming from some module's namespace... is this sort of the idea?
Someone help me wrap my head around this, please. :)

Jul 19 '05 #4
Mac wrote:
Under certain circumstances isinstance() seems to return incorrect
value for me. I'm using Python 2.3 (latest from Debian's unstable).
Here's a sample program... the multi-module nature of the code is key.
Yes, it has the multi-module nature. What it needs, though, is the
Buddha nature :-)


=== test.py ===

class Foo:
pass
'print' and 'repr()' are your friends. Use them.
Add this:
print '*** Have just made class Foo:', repr(Foo)

def test():
from test2 import make_me_a_foo
foo = make_me_a_foo()
Add these lines:
print 'foo is an instance of', foo.__class__
print 'In test, Foo is', repr(Foo)
if isinstance(foo, Foo):
print "is a Foo"
else:
print "is NOT a Foo!"

if __name__ == "__main__":
test()
=== test2.py ===

from test import Foo

def make_me_a_foo():
Add this:
print "In test2, Foo is", repr(Foo)
return Foo()
--8<--

When I run "python test.py", I get "is NOT a Foo!", when the object
clearly IS a Foo!


Indeed foo is an instance of a class named Foo, but it is not the Foo
you are looking for. You have created *TWO* Foo classes. A class is
created when its source is executed. This has happened twice, once when
you ran the test.py script, and again when test2.py imported test.

Circular imports are big trouble (in any language). If you think you
need them, you are wrong; refactor until they go away. Circularly
importing all or some objects from your __main__ script is double trouble.

HTH,

John
Jul 19 '05 #5

"Mac" <id******************@yahoo.com> wrote in message
news:11*********************@g49g2000cwa.googlegro ups.com...
I see, interesting. OK, I understand that recursive importing can be
problematic (having to "hide" the test2 import should have been a tip
off; it's just that in my original app this relationship is not as
clear), but what is the lesson I should take away from this?
I suspect that the import hiding was needed to avoid infinite recursion but
is not essential in itself to getting duplicate class Foo objects.
I mean, I
was under the impression that "once a Foo, always a Foo", while from
the above I'm starting to see that a single class definition can give
rise to a multiple number of classes,
Unless you intend this, it is probably a programming error on your part.
and that the classes are
parametrized by the module they come from (I guess that makes sense...
else class names would have to be unique throughout all the source for
a single program)
There is nothing special about classes here.
... I guess the problem is I'm thinking of "classes"
as these abstract concepts, sort of like Platonian "forms", whereas I
should be thinking of classes as "class objects",
Definitely. In Python, 'everything' is an object. Understanding this is a
key to understanding Python programming.
Someone help me wrap my head around this, please. :)


Here is the source of your particular problem. Running 'python
somefile.py' is more or less equivalent to a hidden single-line program:
'import somefile.py as __main__'. The code in somefile is used to populate
the main module, named '__main__'. If the code in somefile.py (or .pyc)
leads, directly or indirectly, to execution of 'import somefile', the
import function looks for an existing module named (bound to, in
sys.modules, for CPython) 'somefile'. Not finding one, it create a new
module, names it 'somefile', and populates it from somefile.py. Now there
are duplicate modules and probably a program bug.

This is not the only way to get two modules from one file. One can give
import different access paths to a file such that it will not recognize
that it has already imported the file. But this too is almost certainly an
error.

One way people avoid importing the main module file after startup is to
limit it to top-level code with no class or function definitions that might
need to be imported elsewhere. But when a module of definitions, intended
for import, has an "if __name__ == '__main__': test()" section for testing
purposes, then more care may be needed.

Terry J. Reedy

Jul 19 '05 #6
Mac wrote:
[snip]
I guess the problem is I'm thinking of "classes"
as these abstract concepts, sort of like Platonian "forms", whereas I
should be thinking of classes as "class objects", object instances,
each coming from some module's namespace... is this sort of the idea?
Someone help me wrap my head around this, please. :)


Yes, you're getting it; Python is a dynamic language. Even classes can
be created on the fly.

I have a kit for reading/writing boring old legacy mainframe-style files
containg multiple record types with fixed-length fields. The record
definitions are stored as data, not as code. A skeleton class's source
is actually *local* to the class-making function. This means the class
statement is executed each time the function is called. The function
takes the current class instance like a shopping trolley and fills it up
with more methods and attributes, before parking it in a dictionary
keyed on the record name.

Taxpayer = file_dict['TXPYR']
taxpayer = Taxpayer()
taxpayer.name = 'John Q Doe'
taxpayer.date_of_birth = datetime.date(1970, 12, 31)
taxpayer.reportable_income = 1234.56
outfile.write(taxpayer.as_fixed_string())
Cheers,
John
Jul 19 '05 #7
Mac
OK, it's alllll coming together now, thx. Grrr... all this
misconception, again, due to the evil, evil, EVIL influence of having
worked a lot before with an inferior language (C/C++)... :)

Jul 19 '05 #8

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

6
by: Michal Vitecek | last post by:
hello, please consider the following situation: under the current directory there's a subdirectory 'package' with two files: __init__.py and module.py ./package: __init__.py module.py
2
by: | last post by:
I need to find out dynamically if an object is instance of a Class but I don't know how to use this isinstance buit-in function. I have the object and the name of the class, what should I do? ...
5
by: Jordan Rastrick | last post by:
Hi everyone, Just a little issue that I've come across in Python where I'd be interested to read the thoughts and opinions of the great thinkers and programmers who frequent this newsgroup. ...
19
by: Mr.Rech | last post by:
Hi all, I've read some thread about isinstance(), why it is considered harmful and how you can achieve the same results using a coding style that doesn't break polymorphism etc... Since I'm trying...
0
by: Kirk McDonald | last post by:
I'm examining the C API, and I have a question. http://docs.python.org/api/object.html There are two functions that appear to do nearly same thing, and I just want to be certain I'm not...
12
by: codefire | last post by:
Hi, I'm using the isinstance built-in function. I've found the docs for it, but there are no docs on the supported types. For example isinstance(a, int) works fine but isinstance(s, string)...
21
by: abcd | last post by:
In my code I am debating whether or not to validate the types of data being passed to my functions. For example def sayHello(self, name): if not name: rasie "name can't be null" if not...
7
by: Tlis | last post by:
I am using a software system with an embedded Python interpreter (version 2.3) for scripting. The KcsPoint2D.py module contains a Point2D class with the following method: def...
5
by: Boris Borcic | last post by:
Given the ABC innovation, maybe an infix syntax for isinstance() would be good. Possibilities : - stealing "is" away from object identity. As a motivation, true use cases for testing object...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.