something wrong with isinstance

M

maksym.kaban

Hi there.
now i'm a complete newbie for python, and maybe my problem is stupid
but i cannot solve it myself

i have an object of class GeoMap which contains lists with objects of
GeoMapCell (i will not explain what they should do, hope its not
important). Then i want to serialize these objects to json notation.
So i imported json module and as shown in docs for it extended
JSONEncoder class. Look at the code below

##main module
from worldmap import GeoMap, GeoMapCell

import testdata
import json

class GeoMapEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, GeoMap):
return None
return json.JSONEncoder.default(self, obj)

def main():
print(json.dumps(2 + 5j, cls=ComplexEncoder))

geomap = testdata.createTestMap()
print(json.dumps(geomap, cls=GeoMapEncoder))
pass

if __name__ == '__main__':
main()

===========

##worldmap module
class GeoMap:
cells = []
activerow = 0
activecol = 0

def addCell(self, acell):
if len(self.cells) == 0:
self.cells.append([])
self.activerow = 0
acell.col = self.activerow
acell.row = self.activecol
self.cells[self.activerow].append(acell)
self.activecol += 1

def addRow(self):
self.cells.append([])
self.activerow += 1;
self.activecol = 0;

class GeoMapCell:
neighbours = (None, None, None, None, None, None, )
col = 0
row = 0

The problem is in here.

class GeoMapEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, GeoMap): ## <======= isinstance doesnot
work as i expected
return None
return json.JSONEncoder.default(self, obj)

Though obj is object of GeoMap class, isinstance returns False. Where
was i mistaken. If i shouldn't use isinstance, then what function
would check class of object?

Oh, maybe its important. I'm working on WinXP SP3, Python 3.0, IDE -
PyScript
 
P

Paul McGuire

Hi there.
now i'm a complete newbie for python, and maybe my problem is stupid
but i cannot solve it myself

i have an object of class GeoMap which contains lists with objects of
GeoMapCell (i will not explain what they should do, hope its not
important). Then i want to serialize these objects to json notation.
So i imported json module and as shown in docs for it extended
JSONEncoder class.  Look at the code below

##main module
from worldmap import GeoMap, GeoMapCell

import testdata
import json

class GeoMapEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, GeoMap):
            return None
        return json.JSONEncoder.default(self, obj)

def main():
    print(json.dumps(2 + 5j, cls=ComplexEncoder))

    geomap = testdata.createTestMap()
    print(json.dumps(geomap, cls=GeoMapEncoder))
    pass

if __name__ == '__main__':
    main()

===========

##worldmap module
class GeoMap:
    cells = []
    activerow = 0
    activecol = 0

    def addCell(self, acell):
        if len(self.cells) == 0:
          self.cells.append([])
          self.activerow = 0
        acell.col = self.activerow
        acell.row = self.activecol
        self.cells[self.activerow].append(acell)
        self.activecol += 1

    def addRow(self):
        self.cells.append([])
        self.activerow += 1;
        self.activecol = 0;

class GeoMapCell:
    neighbours = (None, None, None, None, None, None, )
    col = 0
    row = 0

The problem is in here.

class GeoMapEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, GeoMap):  ## <=======   isinstance doesnot
work as i expected
            return None
        return json.JSONEncoder.default(self, obj)

 Though obj is object of GeoMap class, isinstance returns False. Where
was i mistaken. If i shouldn't use isinstance, then what function
would check class of object?

Oh, maybe its important. I'm working on WinXP SP3, Python 3.0, IDE -
PyScript

Here's a crazy idea out of left field. Just before calling
isinstance, why not try:

print(type(obj))
print(str(obj))

This may illuminate the unexpected behavior, you'll find out just what
obj has in it.

-- Paul
 
M

maksym.kaban

Here's a crazy idea out of left field.  Just before calling
isinstance, why not try:

print(type(obj))
print(str(obj))

This may illuminate the unexpected behavior, you'll find out just what
obj has in it.

-- Paul

Well the output of
print(type(obj))
print(str(obj))

was

<class 'worldmap.GeoMap'>
<worldmap.GeoMap object at 0x01DD17B0>

Just looks well, isn't it? i have no idea what's wrong
 
R

redbaron

Don't really sure, but try to define your class as new-style one.
Like
class GeoMap(object):
...
 
P

Paul McGuire

Well the output of


was

<class 'worldmap.GeoMap'>
<worldmap.GeoMap object at 0x01DD17B0>

Just looks well, isn't it? i have no idea what's wrong

So then how do you know isinstance is evaluating to False? And why do
you return None if it evals to True? Can you drop a print command
inside the if block just before returning None, and another print just
before returning the default default?

I also would recommend using a debugger like winpdb when in a spot
like this - despite the name, it is not Windows-only, and you can step
through this code and evaluate variables and expressions inline.

-- Paul
 
D

Diez B. Roggisch

Hi there.
now i'm a complete newbie for python, and maybe my problem is stupid
but i cannot solve it myself

i have an object of class GeoMap which contains lists with objects of
GeoMapCell (i will not explain what they should do, hope its not
important). Then i want to serialize these objects to json notation.
So i imported json module and as shown in docs for it extended
JSONEncoder class. Look at the code below

##main module
from worldmap import GeoMap, GeoMapCell

import testdata
import json

class GeoMapEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, GeoMap):
return None
return json.JSONEncoder.default(self, obj)

def main():
print(json.dumps(2 + 5j, cls=ComplexEncoder))

geomap = testdata.createTestMap()
print(json.dumps(geomap, cls=GeoMapEncoder))
pass

if __name__ == '__main__':
main()

===========

##worldmap module
class GeoMap:
cells = []
activerow = 0
activecol = 0

def addCell(self, acell):
if len(self.cells) == 0:
self.cells.append([])
self.activerow = 0
acell.col = self.activerow
acell.row = self.activecol
self.cells[self.activerow].append(acell)
self.activecol += 1

def addRow(self):
self.cells.append([])
self.activerow += 1;
self.activecol = 0;

class GeoMapCell:
neighbours = (None, None, None, None, None, None, )
col = 0
row = 0

The problem is in here.

class GeoMapEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, GeoMap): ## <======= isinstance doesnot
work as i expected
return None
return json.JSONEncoder.default(self, obj)

Though obj is object of GeoMap class, isinstance returns False. Where
was i mistaken. If i shouldn't use isinstance, then what function
would check class of object?

Oh, maybe its important. I'm working on WinXP SP3, Python 3.0, IDE -
PyScript


I think you have a common problem here that occurs when using a script
with more that non-trivial contents as main-script.


What happens is this: you have a

__main__.GeoMap, which is the one tested against in isinstance.

*And* you have a <mainmodule>.GeoMap (replace <mainmodule> with the
actual name) that is imported & used from the other module.


A simple testscript illustrates the issue:


### test.py ####

class Foo(object):
pass


if __name__ == "__main__":
import test
print Foo == test.Foo


Run it from inside the directory you saved it in.

To work around this issue, simply create a bootstrap-main-module that
has not much in it.

Diez
 
B

Bruno Desthuilliers

(e-mail address removed) a écrit :
Hi there.
now i'm a complete newbie for python, and maybe my problem is stupid
but i cannot solve it myself

Others already addressed your problem (cf Paul and Diez answers). I'll
just allow myself to point a couple other potential problems with your code:
##worldmap module
class GeoMap:
cells = []
activerow = 0
activecol = 0


Attributes defined at the class level are *class* attributes, shared by
all instances of the class - that is, all instances will access the one
same 'cells' list. Instance attributes are canonically created in the
initialize method (__init__) that is automagically called on
instanciation. IOW, you want to replace the above lines with:

def __init__(self):
self.cells = []
self.activerow = 0
self.activecol = 0

def addCell(self, acell):
if len(self.cells) == 0:

An empty list evals to False in a boolean context, so the above can be
simply expressed as:
if not self.cells:
self.cells.append([])
self.activerow = 0
acell.col = self.activerow
acell.row = self.activecol
self.cells[self.activerow].append(acell)
self.activecol += 1

def addRow(self):
self.cells.append([])
self.activerow += 1;
self.activecol = 0;

class GeoMapCell:
neighbours = (None, None, None, None, None, None, )
col = 0
row = 0

Same remark as above. You want to move all this code to the __init__ method.
 
C

Carl Banks

Don't really sure, but try to define your class as new-style one.
Like
class GeoMap(object):
   ...

Well, the OP said he was using Python 3.0, where all classes are new-
style classes.

But that brings up another very slight possibility, though not a very
likely one in this case: the behavior of isinstance can be
customized. It can happen unbeknownst to a user who subclasses a
class that does that.


Carl Banks
 
G

Gabriel Genellina

Well, the OP said he was using Python 3.0, where all classes are new-
style classes.

But that brings up another very slight possibility, though not a very
likely one in this case: the behavior of isinstance can be
customized. It can happen unbeknownst to a user who subclasses a
class that does that.

Really? I didn't know that -- how do you do that?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,260
Messages
2,571,039
Members
48,768
Latest member
first4landlord

Latest Threads

Top