Build an object that may or may not be packaged

So, I have this (of course, the true thing is more complicated):

class test(object):
    i = -1

    def keys(self):
        return ["a", "b"]

    def __getitem__(self, item):
        return {"a": 0, "b": 1}[item]

    def __len__(self):
        return 2

    def __contains__(self, item):
        if item in ["a", "b"]:
            return True
        return False

    def __iter__(self):
        return self

    def next(self):
        self.i += 1
        if self.i > 1:
            raise StopIteration()

        return ["a", "b"][self.i]

What I want to do is (again, the true thing is more complicated):

> t = test()
> dict(t)
 {'a': 0, 'b': 1}
> dict(**t) 
 {'a': 0, 'b': 1}

This works fine, but it doesn’t work if I define the class as a subclass of dict, and this is what I want, I want my object to behave like a dict with some hidden tricks under the knees (and again sure that makes sense in real code):

class test(dict):
     .... same code here ....

In this case, dict(t)they dict(**t)will return an empty dictionary {}, but [k for k in t]will return ['a','b'].

What am I missing? It seems that I need to override some dict function, although the method __getitem__, __iter__, __len__, __contains__ and keyswas enough to do the trick. I tried updating iterkeys, itervalues, copy, get, etc., but nothing works.

Thank.

+4
1
 class test(dict):
    i = -1

    def __init__(self):
        super(test, self).__init__({"a": 0, "b": 1})

    def keys(self):
        return ["a", "b"]

    def __getitem__(self, item):
        return {"a": 0, "b": 1}[item]

    def __len__(self):
        return 2

    def __contains__(self, item):
        if item in ["a", "b"]:
            return True
        return False

    def __iter__(self):
        return self

    def next(self):
        self.i += 1
        if self.i > 1:
            raise StopIteration()

        return ["a", "b"][self.i]

t = test()
print dict(t)
# output: {'a': 0, 'b': 1}
print dict(**t)
# output: {'a': 0, 'b': 1}

, hardcode {'a': 0, 'b': 1} .

0

Source: https://habr.com/ru/post/1532685/


All Articles