Heim  >  Artikel  >  Backend-Entwicklung  >  Einführung in benutzerdefinierte Python-Objekte zur Implementierung der Slicing-Funktion (Codebeispiel)

Einführung in benutzerdefinierte Python-Objekte zur Implementierung der Slicing-Funktion (Codebeispiel)

不言
不言nach vorne
2018-12-30 10:40:502759Durchsuche

Der Inhalt dieses Artikels ist eine Einführung in die Slicing-Funktion von benutzerdefinierten Python-Objekten (Codebeispiele). Ich hoffe, dass er für Sie hilfreich ist.

1. Magische Methode: __getitem__()

Es ist nicht schwierig, ein benutzerdefiniertes Objekt zu erstellen, das die Slicing-Syntax unterstützt magische Methode __getitem__(). Lassen Sie uns zunächst diese Methode vorstellen.

Syntax: object.__getitem__(self, key)

Offizielle Dokumenterklärung: Wird aufgerufen um die Auswertung von self[key] zu implementieren. Für Sequenztypen wird das akzeptiert Schlüssel sollten Ganzzahlen und Slice-Objekte sein. Beachten Sie, dass das Besondere Interpretation negativer Indizes (wenn die Klasse a emulieren möchte). Sequenztyp) hängt von der Methode __getitem__() ab Bei einem ungeeigneten Typ kann TypeError ausgelöst werden, wenn es sich um einen Wert handelt außerhalb des Satzes von Indizes für die Sequenz (nach jedem Sonderzeichen). Interpretation negativer Werte), IndexError sollte ausgelöst werden Zuordnungstypen: Wenn der Schlüssel fehlt (nicht im Container), sollte KeyError auftreten ausgelöst werden.

Eine zusammenfassende Übersetzung: Die Methode __getitem__() wird verwendet, um den Parameterschlüssel zurückzugeben Der entsprechende Wert, dieser Schlüssel, kann ein ganzzahliger Wert oder ein Slice-Objekt sein und unterstützt negative Indizes. Wenn der Schlüssel nicht zu den beiden oben genannten Typen gehört, wird er ausgelöst TypeError; wenn der Index außerhalb der Grenzen liegt, wird IndexError ausgelöst; wenn ein Zuordnungstyp definiert ist und der Schlüsselparameter nicht der Schlüsselwert seines Objekts ist, wird er ausgelöst Schlüsselfehler.

2. Passen Sie die Sequenz an, um die Slicing-Funktion zu implementieren

Als nächstes definieren wir eine einfache MyList und fügen ihr die Slicing-Funktion hinzu. (PS: Nur zur Demonstration, die Vollständigkeit anderer Funktionen kann nicht garantiert werden).

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

Den Ausgabeergebnissen nach zu urteilen, unterstützt die angepasste MyList sowohl die Suche nach Index als auch Slicing-Vorgänge, was genau unser Zweck ist.

Besonders zu beachten ist, dass in diesem Beispiel __getitem__() verwendet wird Die Methode implementiert je nach Parametertyp unterschiedliche Funktionen (Erhalten des Indexbitwerts oder Slice-Werts) und behandelt Ausnahmen entsprechend, sodass wir keine umständliche Verarbeitungslogik schreiben müssen. Es gibt viele Lernmaterialien im Internet, die völlig irreführend sind. Sie lehren Sie, verschiedene Arten von Parametern zu unterscheiden und dann einen großen Code zu schreiben, um die Indexsuche und die Slicing-Syntax zu implementieren. Das Folgende ist ein repräsentatives Fehlerbeispiel:

###略去其它代码####
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. Benutzerdefiniertes Wörterbuch zur Implementierung der Slicing-Funktion

Slicing ist eine Funktion des Sequenztyps, also im obigen Beispiel: Wir müssen die spezifische Implementierungslogik des Slicings nicht schreiben. Für andere Nicht-Sequenztypen benutzerdefinierter Objekte müssen Sie die Slicing-Logik jedoch selbst implementieren. Nehmen Sie als Beispiel ein benutzerdefiniertes Wörterbuch (PS: Dies dient nur zur Demonstration und die Vollständigkeit anderer Funktionen kann nicht garantiert werden):

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

Der entscheidende Punkt des obigen Beispiels besteht darin, die Schlüsselwerte herauszunehmen ​​des Wörterbuchs und segmentieren Sie die Liste der Schlüsselwerte. Das Schöne an der Verarbeitung ist, dass Sie sich keine Gedanken über Index außerhalb der Grenzen und negative Indizes machen müssen und das Wörterbuchsegment in ein Wörterbuchsegment umgewandelt wird Schlüsselwerte, und das Ziel ist endlich erreicht.

4. Zusammenfassung

Abschließende Zusammenfassung: Dieser Artikel stellt die magische Methode __getitem__() vor und wird zum Implementieren benutzerdefinierter Objekte verwendet (am Beispiel von Listentypen und Wörterbuchtypen). Ich hoffe, dass die Slicing-Funktion für Sie hilfreich ist.

Das obige ist der detaillierte Inhalt vonEinführung in benutzerdefinierte Python-Objekte zur Implementierung der Slicing-Funktion (Codebeispiel). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:segmentfault.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen