Ask Your Question
0

Problem with Sequence command

asked 2016-09-26 11:24:23 -0500

_pk gravatar image

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?

Thanks in advance, Przemek

edit retag flag offensive close merge delete

1 answer

Sort by ยป oldest newest most voted
0

answered 2016-10-18 20:49:59 -0500

fidbc gravatar image

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()
edit flag offensive delete link more

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

1 follower

Stats

Asked: 2016-09-26 11:24:23 -0500

Seen: 37 times

Last updated: Oct 18 '16