2

I am studying ways to forward object methods in order to modify some of them and leave the rest as they are.

I thought that if it is possible to get __getitem__ as a field, it should be possible to use square brackets and len as well, but apparently it is not:

class Wrapper:
    def __init__(self, x):
        self.__dict__['__wrapped_obj'] = x

    def __getattribute__(self, item):
        if item == '__dict__':
            return super().__getattribute__(item)
        print('They be gettin "{}"'.format(item))
        return self.__dict__['__wrapped_obj'].__getattribute__(item)

    def __setattribute__(self, item, v):
        print('They be settin "{}"'.format(item))
        return setattr(self.__dict__['__wrapped_obj'], item, v)

class Wrapper2:  # gives same results
    def __init__(self, x):
        for k in dir(x):
            if k not in ('__class__', ):
                setattr(self, k, getattr(x, k))
        self.__dict__['__wrapped_obj'] = x

a = Wrapper([])
a.append(5)
print(a.__getitem__(0))  # 5
len(a)                   # TypeError: object of type 'Wrapper' has no len()
a[0]                     # TypeError: 'Wrapper' object does not support indexing

So Python internally uses something else than item's __dict__ to find magic methods?

Alex
  • 1,165
  • 2
  • 9
  • 27
  • maybe this could help: https://stackoverflow.com/questions/7642434/is-there-a-way-to-implement-methods-like-len-or-eq-as-classmethods – Jean-François Fabre Nov 15 '18 at 16:46
  • 1
    `a[0]` won't work since you haven't actually implemented `__getitem__` anywhere? Sorry for the stupid question, I don't see any other way unless you're trying to magically call it by trying to pass through `__getattribute__` in a way i'm unfamiliar with. – Torxed Nov 15 '18 at 16:47
  • And you would also need to implement `__len__`, if again, you're not doing something magical I'm unaware of. But since you're passing alone a list (`x`) and you're trying to do work on it, that in of itself isn't a dictionary just because you're placing it in one.. It's still a list and your class needs the dictionary substitutes of those function in order to act like a dictionary. – Torxed Nov 15 '18 at 16:57
  • @roeen30, yup! TL;DR for future visitors: `magic(x)` is equivalent to `type(x).__magic__(x)` – Alex Nov 15 '18 at 17:41

0 Answers0