Class attributes / methods lost?

Jean-Michel Pichavant jeanmichel at sequans.com
Mon Mar 1 10:09:22 EST 2010


Gabor Urban wrote:
> Hi guys,
>
> I am building a nested data structure with the following compontens:
>
> <>
>
> class Item:
>     def __init__(self, pId, pChange, pComment):
>         self.ID = pId
>         self.Delta = pChange
>         self.Comment = pComment
>
>     def PrintItem(self):
>         str = '%s,%s,%s'%(self.ID,self.Delta,self.comment)
>         return str
>
> class Package:
>     def __init__(self, pSerial, pDate, pOwner, pSchema):
>         self.serial = pSerial
>         self.date = pDate
>         self.owner = pOwner
>         self.schema = pSchema
>         self.items = []
>
>     def insertItem(self, pItem):
>         self.items.append(pItem)
>
>     def printPackage(self):
>         lines = []
>         str = '%s,%s,%s,%s'%(self.serial,self.date,self.owner,self.schema)
>         number = self.items.length
>         for idx in xrange(number):
>             line = ''
>             istr = self.items[idx].PrintItem()
>             line = str + ',' + istr
>             lines.append(line)
>         return lines
>
> <>
>
> The above structure is processed with next code:
>
> <>
>
> size = len(packages)
> package = None
> for index in xrange(size):
>     logger.info('PrettyPrinting package id=%d',index)
>     oplines = []
>     oplines = packages[index].printPackage()
>     for i in xrange(oplines.length):
>         data.append(oplines[i])
> <>
>
> I've got the next error message:
> ' Traceback (most recent call last):
>   File "XmlHistory_orig.py", line 203, in ?
>     oplines = packages[index].printPackage()
> TypeError: unbound method printPackage() must be called with Package
> instance as first argument (got nothing instead) '
>
> I did give a try to access the fields directly
>
> <>
> packages = []
> data = []
>
> size = len(packages)
> for index in xrange(size):
>     str = '%s,%s,%s,%s'%(packages[index].serial,packages[index].date,packages[index].owner,packages[index].schema)
>     itemnum = len(packages[index].items)
>     oplines = []
>     for itemIndx in xrange(itemnum):
>         element =
> '%s,%s,%s'%(packages[index].items[itemIdx].ID,packages[index].items[itemIdx].Delta,packages[index].items[itemIdx].comment)
>         oplines.append(str + ','+elemt)
>
> <>
>
> Error:
>
> Traceback (most recent call last):
>   File "XmlHistory.py", line 204, in ?
>     str = '%s,%s,%s,%s'%(packages[index].serial,packages[index].date,packages[index].owner,packages[index].schema)
> AttributeError: class Package has no attribute 'serial'
>
> The strange in this issue for me, that I do not see why are the class
> methods and fields lost.
>
> Any idea is wellcome.
>
> Gabor
>   
Ok here are some suggestions :

1/ do not name a method PrintItem if the method does not print anything 
(it does not)
2/ use the __str__ method to return a nice representation of your objects
3/ use pythonic iteration controls
4/ be consistant with your naming convention, your Item's attributes 
start with an Uppercase letter, Package's attributes with a lowercase 
one. (I suggest the lowercase)


class Item(object):
    def __init__(self, pId, pChange, pComment):
        self.id = pId
        self.delta = pChange
        self.comment = pComment

    def __str__(self):
        return self.__class__.__name__ + ':' + str(self.__dict__)

class Package(object):
    def __init__(self, pSerial, pDate, pOwner, pSchema):
        self.serial = pSerial
        self.date = pDate
        self.owner = pOwner
        self.schema = pSchema
        self.items = []

    def insertItem(self, pItem):
        self.items.append(pItem)

    def __str__(self):
        _dict = self.__dict__.copy()
        _dict['items'] = [str(item) for item in self.items]
        return self.__class__.__name__ + ':' + str(_dict)

i1 = Item('a', 'b', 'c')
i2 = Item('foo', 'bar', 'baz')
p = Package(1,2,3,4)
p.insertItem(i1)
p.insertItem(i2)
packages = [p]

for package in packages:
    print package

 >>> Package:{'date': 2, 'owner': 3, 'serial': 1, 'schema': 4, 'items': 
["Item:{'comment': 'c', 'id': 'a', 'delta': 'b'}", "Item:{'comment': 
'baz', 'id': 'foo', 'delta': 'bar'}"]}

Regarding the error you get, it seems you've stored the class itself, 
instead instances.
The error should be in the way you've built the package list, but you 
did not provide the code.

JM




More information about the Python-list mailing list