Lesson 047: magic method: customized sequence | after class test questions and answers

Posted by TheTechChik on Sat, 29 Jan 2022 12:57:32 +0100

Test questions (written test, no computer ~):

0. Do you know what Python's three sequence based container classes refer to?

A: it's undoubtedly a List, Tuple and String.

1. Python allows us to customize containers. If you want to customize an immutable container (like String), what methods can't you define?

A: if you want to customize an immutable container (like String), you can't define an immutable container__ setitem __ () and__ delitem __ () these methods modify the data in the container.

2. If you want the customized container to support the built-in function of reversed(), what method should you define?

Answer: it should be defined__ reversed __ () method, which provides support for the built-in function reversed().

3. Since it is a container, it is necessary to provide a method to query the "capacity", so what method needs to be defined?

A: in Python, we query the "capacity" of the container through the built-in function of len(), so the container should be defined__ len __ () method.

4. What methods are defined to enable the container to support read, write and delete operations?

Answer: read -__ getitem __ (), write -__ setitem __ (), delete -__ delitem __ (),

5. Why does the little turtle say "the protocol in Python is not so formal"?

A: in Python, the protocol is more like a guide. This is a bit like the "duck type" we mentioned in our homework before (please stamp if you forget): http://bbs.fishc.com/thread-51471-1-1.html )-- when you see a bird walking like a duck, swimming like a duck and barking like a duck, then the bird can be called a duck. Python is like this. It doesn't strictly require you how to do it, but let you do things well with consciousness and experience!

Do it yourself (be sure to try it yourself ~):

0. Customize a list according to the examples in the class. It is also required to record the number of times each element in the list is accessed. This time, we hope that the customized list functions will be more comprehensive, such as supporting the methods owned by the native list of append(), pop(), and extend(). How should you modify it?

Requirement 1: implement the behavior of obtaining, setting and deleting an element (when deleting an element, the corresponding counter will also be deleted)
Requirement 2: add the counter(index) method to return the number of accesses to the element record specified by the index parameter
Requirement 3: implement the append(), pop(), remove(), insert(), clear() and reverse() methods (when rewriting these methods, pay attention to the corresponding changes of counters)
There is only one practical question today, but when writing code, always consider that your list has added counter function, so please be sure to consider carefully before submitting the answer.

Examples in class:

class CountList:
        def __init__(self, *args):
                self.values = [x for x in args]
                self.count = {}.fromkeys(range(len(self.values)), 0)

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

        def __getitem__(self, key):
                self.count[key] += 1
                return self.values[key]

Answer: in order to achieve so many functions, we can no longer use a dictionary to store the count of elements. Because for the list, if you delete one element, the subscript of other elements will change accordingly (the dictionary using subscript as key will certainly not be able to deal with it freely). Therefore, we use a list to store the count of corresponding elements.

The CountList class below inherits and relies heavily on the behavior of its parent class (list), and overrides some methods as required.

class CountList(list):
    def __init__(self, *args):
        super().__init__(args)
        self.count = []
        for i in args:
            self.count.append(0)

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

    def __getitem__(self, key):
        self.count[key] += 1
        return super().__getitem__(key)

    def __setitem__(self, key, value):
        self.count[key] += 1
        super().__setitem__(key, value)

    def __delitem__(self, key):
        del self.count[key]
        super().__delitem__(key)

    def counter(self, key):
        return self.count[key]

    def append(self, value):
        self.count.append(0)
        super().append(value)

    def pop(self, key=-1):
        del self.count[key]
        return super().pop(key)

    def remove(self, value):
        key = super().index(value)
        del self.count[key]
        super().remove(value)

    def insert(self, key, value):
        self.count.insert(key, 0)
        super().insert(key, value)

    def clear(self):
        self.count.clear()
        super().clear()

    def reverse(self):
        self.count.reverse()
        super().reverse()

Topics: Python