0

I have the following code:

class Stat(list):
    def __init__(self, lst = []):
        self.s = list(lst)

    def __repr__(self):
        return "Stat({})".format(self.s)

    def add(self, item):
        self.s.append(item)

    def len(self):       
        return len(self.s)

...(more methods, but not necessary)

All of the methods work properly but len(). No matter the length of the Stat object, the returned length is always 0; I don't understand why.

Frank
  • 339
  • 8
  • 18
  • 1
    How are you creating the Stat object and calling the `len` method? – skrrgwasme Apr 19 '16 at 05:43
  • first add some item in 1st array – Jigar Apr 19 '16 at 05:46
  • 1
    You probably shouldn’t be inheriting from `list`. – Ry- Apr 19 '16 at 05:46
  • @ skrrgwasme that's where I'm confused. When creating a Stat object it's created as a list, but since I'm inheriting the `list` class I would think the `len` method would work on the Stat object. How else would I get the length of the object? – Frank Apr 19 '16 at 05:47
  • @Frank We'd be able to help if you shared the code. – skrrgwasme Apr 19 '16 at 05:48
  • @Ryan O'Hara in that case how would I get the length of the object? – Frank Apr 19 '16 at 05:48
  • When `my_stat = Stat([1,2,3])` Do you call it `my_stat.len()` or `len(my_stat)`? – Byte Commander Apr 19 '16 at 05:48
  • 5
    If you want to be able to do `len(Stat())`, the special method name is `__len__`. The right way to call the `len` method (as it’s just a method named `len`) on your current class is just `Stat().len()`. But you wouldn’t need to inherit from `list` to do either of these. Pick one of wrapping `list` (having `self.s`) or inheriting from it. – Ry- Apr 19 '16 at 05:48
  • @ByteCommander calling it as `len(my_stat)` – Frank Apr 19 '16 at 05:48
  • 2
    On the note of not inheriting from list, further reading [here](http://stackoverflow.com/questions/36688966/let-a-class-behave-like-its-a-list-in-python/36690145) – timgeb Apr 19 '16 at 05:53

4 Answers4

7

it will return 0 always when you are using it like this:

x = Stat([1,3,4,5])
print len(x)

if you want to override len function use this code:

def __len__(self):       
    return len(self.s)
János Farkas
  • 453
  • 5
  • 14
  • This solved it! Don't know why I didn't try this... Thanks! – Frank Apr 19 '16 at 05:52
  • @Frank I think you inherited from `list` in order to be able to do `len(myobj)`. Seriously consider not inheriting from `list` now that you know that `def __len__(self)` is the key to be able to do `len(myobj)`. – totoro Apr 19 '16 at 06:04
0
s = Stat([1, 2])
s.add(1)
s.add(2)
print s.len()

I have run your code, the result is correct in my environment.

Josh
  • 11
  • 2
0

Override the magic method __len__(self) to control the output of a call to len(my_stat_object):

class Stat(list):
    def __init__(self, lst = []):
        self.s = list(lst)

    def __repr__(self):
        return "Stat({})".format(self.s)

    def add(self, item):
        self.s.append(item)

    def __len__(self):       
        return len(self.s)
Byte Commander
  • 6,506
  • 6
  • 44
  • 71
0

If what you're trying to run is len(stat) and not stat.len(), your function len should be named __len__ instead. Here's the docs: object.len

stat = Stat([1, 2])
len(s) # 0 if len, 2 if __len__

As a side note, you might want to replace lst=[] in your init definition, as it can cause some weird looking behaviours. Read about it here: mutable default argument

Community
  • 1
  • 1
Miles
  • 100
  • 1
  • 10