Home  >  Article  >  Backend Development  >  Introduction to Python custom objects to implement slicing function (code example)

Introduction to Python custom objects to implement slicing function (code example)

不言
不言forward
2018-12-30 10:40:502711browse

The content of this article is an introduction to the slicing function of Python custom objects (code examples). It has certain reference value. Friends in need can refer to it. I hope it will be helpful to you.

1. Magic method: __getitem__()

It is not difficult to make a custom object support slicing syntax. You only need to provide it when defining the class. It implements the magic method __getitem__(). So, let’s first introduce this method.

Syntax: object.__getitem__(self, key)

Official document definition: Called to implement evaluation of self[key]. For sequence types, the accepted keys should be integers and slice objects. Note that the special interpretation of negative indexes (if the class wishes to emulate a sequence type) is up to the __getitem__() method. If key is of an inappropriate type, TypeError may be raised; if of a value outside the set of indexes for the sequence (after any special interpretation of negative values), IndexError should be raised. For mapping types, if key is missing (not in the container), KeyError should be raised.

Summary translation: The __getitem__() method is used to return the parameter key The corresponding value, this key can be an integer value or a slice object, and supports negative indexes; if the key is not the above two types, it will throw TypeError; if the index is out of bounds, IndexError will be thrown; if a mapping type is defined, when the key parameter is not the key value of its object, it will be thrown KeyError.

2. Customize the sequence to implement the slicing function

Next, we define a simple MyList and add the slicing function to it. (PS: For demonstration only, the completeness of other functions is not guaranteed).

class MyList():
    def __init__(self):
        self.data = []
    def append(self, item):
        self.data.append(item)
    def __getitem__(self, key):
        print("key is : " + str(key))
        return self.data[key]

l = MyList()
l.append("My")
l.append("name")
l.append("is")
l.append("Python猫")

print(l[3])
print(l[:2])
print(l['hi'])

### 输出结果:
key is : 3
Python猫
key is : slice(None, 2, None)
['My', 'name']
key is : hi
Traceback (most recent call last):
...
TypeError: list indices must be integers or slices, not str

Judging from the output results, the customized MyList supports both search by index and slicing operations, which is exactly our purpose.

Special note is that __getitem__() in this example The method will implement different functions (get the index bit value or slice value) according to different parameter types, and will also handle exceptions appropriately, so we do not need to write cumbersome processing logic. There are a lot of learning materials on the Internet that are completely misleading. They will teach you to distinguish different types of parameters, and then write a large piece of code to implement index search and slicing syntax. It is simply superfluous. The following is a representative error example:

###略去其它代码####
def __getitem__(self, index):
    cls = type(self)
    if isinstance(index, slice):  # 如果index是个切片类型,则构造新实例
       return cls(self._components[index])
    elif isinstance(index, numbers.Integral):  # 如果index是个数,则直接返回
        return self._components[index]
    else:
        msg = "{cls.__name__} indices must be integers"
        raise TypeError(msg.format(cls=cls))

3. Custom dictionary to implement slicing function

Slicing is a feature of the sequence type, so in the above example, We don't need to write the specific implementation logic of slicing. However, for other non-sequence types of custom objects, you have to implement the slicing logic yourself. Take a custom dictionary as an example (PS: This is for demonstration only, and the completeness of other functions is not guaranteed):

class MyDict():
    def __init__(self):
        self.data = {}
    def __len__(self):
        return len(self.data)
    def append(self, item):
        self.data[len(self)] = item
    def __getitem__(self, key):
        if isinstance(key, int):
            return self.data[key]
        if isinstance(key, slice):
            slicedkeys = list(self.data.keys())[key]
            return {k: self.data[k] for k in slicedkeys}
        else:
            raise TypeError

d = MyDict()
d.append("My")
d.append("name")
d.append("is")
d.append("Python猫")
print(d[2])
print(d[:2])
print(d[-4:-2])
print(d['hi'])

### 输出结果:
is
{0: 'My', 1: 'name'}
{0: 'My', 1: 'name'}
Traceback (most recent call last):
...
TypeError

The key point of the above example is to take out the key values ​​​​of the dictionary and slice the list of key values ​​​​The beauty of processing is that there is no need to worry about index out-of-bounds and negative indexes, and the dictionary slice is converted into a slice of dictionary key values, and the goal is finally achieved.

4. Summary

Final summary: This article introduces the __getitem__() magic method and is used to implement custom objects (taking list types and dictionary types as examples )'s slicing function, I hope it will be helpful to you.

The above is the detailed content of Introduction to Python custom objects to implement slicing function (code example). For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:segmentfault.com. If there is any infringement, please contact admin@php.cn delete