2

I'm trying to build some kind of generic wrapper class to hold variable objects.

class Var:
    def __init__(self, obj=None):
        self.obj=obj

    def __getattr__(self, attr):
        return getattr(self.obj, attr)

Now for example, when I try to use it with list as obj, I get different behavior when calling __len__ attribute or len built-in function.

v1 = Var([1,2,3])

print(v1.__len__())
# output: 3

print(len(v1))
# output: TypeError: object of type 'Var' has no len()

That happens with other built-in functions as well. My questions are:

  1. What in those functions implementation is causing the different behavior.

  2. How can I bring Var class to work with len as well.

yonayaha
  • 47
  • 7

1 Answers1

2

You have to implement your own __len__ method inside Var class. Something like this:

class Var:
    def __init__(self, obj=None):
        self.obj=obj

    def __getattr__(self, attr):
        return getattr(self.obj, attr)

    def __len__(self):
        return len(self.obj)

v1 = Var([1,2,3])

print(v1.__len__())
print(len(v1))

output:

pawel@pawel-XPS-15-9570:~/test$ python len.py 
3
3

And here you have some information about differences between len() and __len__: Difference between len() and .__len__()?

pawelbylina
  • 1,387
  • 10
  • 17
  • 1
    Yes, that's an option, but I prefer not to implement every python predefined function this way. It'll be nice to find a generic way to do so. – yonayaha Aug 21 '19 at 10:21
  • What are you trying to do? Why is necessary for you to do `len()` on instances? – pawelbylina Aug 21 '19 at 11:29
  • `len()` is not the issue. I want to be able to call any functions on `Var` object and to get the results of this function on the internal object. – yonayaha Aug 21 '19 at 14:17
  • So here you have an example if I understood the problem: https://stackoverflow.com/a/28579925/2156813 – pawelbylina Aug 22 '19 at 06:37
  • "What are you trying to do?" This seems useful when creating wrappers. When wrapping a list for example you often want `__len__` and `__getitem__`. I think also `__iter__`, `__delitem__`? There are quite a few you need to specify when wrapping objects. – AnnanFay Oct 20 '20 at 14:06