# Problem with Sequence command

Computation of gcd of objects of a class a created fails. I investigated the case and traced down that the problem lies in Sequence command. Consider the following example class:

class foo(object) :
def __init__(self, L_) :
self.L = deepcopy(L_)

def __getitem__(self, j) :
return self.L[j]

def size(self) :
return len(self.L)


Create and example object:

a = foo( [1,2,3] )
print a.size()


3

Build a nested object:

A = foo([ foo([1,2,3]), foo([2,4,8]), foo([1,1]), foo([1]) ])
print A.size()


4

Everything works as expected. So let's iterate over A:

for a in A :
print a.size()


3 3 2 1

So far so good. Let's use Sequence as gcd internally does:

S = Sequence(A)
for s in S :
print s.size()


TypeError: object of type 'foo' has no len()

And boom! Something went wrong. Try to call len explicitly:

for s in S :
print len(s.L)


TypeError: object of type 'foo' has no len()

The same error! Surprisingly the following code actually works (but IMHO it should not):

for s in S :
print len(s.L.L)


3 3 2 1

It seems like something strange happens in initialization. When creating a sequence, all objects get initialized by themselves.

Ok. So here is my question: what's up? Do I do something wrong or is this a bug in Sequence? I know that Python does not provide copy constructors, hence how to initialize objects to avoid this kind of problems?

edit retag close merge delete

Sort by » oldest newest most voted

There is no bug in Sequence. What is happening is you are creating a foo object filled with foos. However, when you compute the size of the outer foo this will request the length of the inner foo and your current implementation of foo has no way of reporting its length. A possible workaround would be to implement the __len__ method instead of having the size method.

Or if you prefer to have them side by side:

class foo(object) :
def __init__(self, L_) :
self.L = deepcopy(L_)

def __getitem__(self, j) :
return self.L[j]

def size(self) :
return len(self.L)
def __len__(self):
return self.size()

more