Im
vorherigen Artikel haben wir einige interessante Punkte der Python-Sprache untersucht. Natürlich sind sie nicht auf einen Artikel beschränkt, daher werden wir fortfahren.
Ein Kommentar untersuchte den folgenden Code:
SEX = 'Female', 'Male' sex = SEX[True]
Es funktioniert, weil der logische Datentyp 0 und 1 entspricht. Außerdem gab es
zu Beginn keinen speziellen Typ und die Werte 0 und 1 wurden verwendet. Und als er eingegeben wurde, haben wir beschlossen, vom Ganzen zu erben.
print(int.__subclasses__())
Zurück zum Abrufen der Listenwerte: Nehmen wir an, wir haben die folgenden Daten:
books = [["Sherlock Holmes", "Arthur Conan Doyle", 1986, True, 12.51], ["The Lost World", "Arthur Conan Doyle", 2015, False, 5.95], ["The Art of Computer Programming", "Donald E. Knuth ", 2017, True, 190.54] ]
Es ist natürlich nicht unser Weg, auf Werte durch fest codierte Indizes zu verweisen. Sie können eine Konstante, z. B. AUTHOR, erstellen und angeben, aber Sie können noch weiter gehen:
TITLE_AUTHOR = slice(0, 2) PRICE_IN_STOCK = slice(3, 5) print(books[0][TITLE_AUTHOR]) print([book for book in books if book[PRICE_IN_STOCK] > [True, 10.0]])
Wir können ein
Slice- Objekt erstellen und ihm angeben, an welchen Indizes sich die interessierenden Felder befinden. Wir können sogar mutig genug sein, etwas Ähnliches wie die letzte Zeile in diesem Block zu schreiben, in der Bücher angezeigt werden, die im Lager verfügbar und teurer als alles andere sind. Dieser Code funktioniert, da der Vergleich von Listen und Tupeln lexikografisch erfolgt: Zuerst werden die ersten Elemente verglichen, dann das zweite usw. Das heißt, jedes Objekt, dessen "Feld" in_stock falsch ist, ist kleiner als die Liste [True, 10.0] Richtig> Falsch.
Hinweis: Natürlich sollte dieser Code nicht in Projekten verwendet werden. Es ist jedoch besser, sich darauf zu beschränken, nur einige Werte für das Slice abzurufen. Es ist besser, eine Auswahl in der Datenbank zu treffen, entweder in Pandas oder als Methode der Book-Klasse. Sie können namedtuple verwenden und ein kleines Modul schreiben, in das Methoden mit ähnlicher Auswahl eingefügt werden.
Wir haben bereits die Argumente berücksichtigt, die nur per Schlüssel an die Funktion übergeben werden können. Als ich kürzlich die
Dokumentation für die Bool-Funktion studierte , fand ich einen Index:
In Version 3.7 geändert: x ist jetzt ein Nur-Positions-Parameter.
Derzeit wird
PEP 570 entwickelt, wodurch die Möglichkeit zum Einstellen solcher Parameter eröffnet wird. Dies kann nützlich sein, wenn der Parametername keine Rolle spielt, z. B. bool (), pow () usw.
Die Entwurfssyntax sieht folgendermaßen aus:
def name(positional_only_parameters, /, positional_or_keyword_parameters, *, keyword_only_parameters):
Zurück zur Bool-Funktion, die genau wie das Einchecken von Bedingungen und Schleifen beim Ausführen von Code funktioniert
if obj:
Python führt eine ziemlich
interessante Prozedur zum Ausgeben eines booleschen Werts aus:
- Wenn das Objekt die Methode __bool __ () implementiert, wird das Ergebnis des Aufrufs dieser Methode zurückgegeben
- Andernfalls wird geprüft, ob die Methode __len __ () implementiert ist. Wenn ja, wird geprüft, ob sie zurückgibt. Wenn 0, ist das Ergebnis False.
- Wenn keine der beiden Methoden implementiert ist, wird True zurückgegeben.
class A: pass a = A() print(bool(a))
Ganzzahlen implementieren die Methode __bool__, Standardauflistungen implementieren sie nicht, implementieren jedoch die Methode __len__:
print(dir(int))
In
einem anderen Kommentar wurde das "nicht standardmäßige" Verhalten von Klassenattributen angegeben:
class Example: arr=[] def __init__(self): pass a = Example() b = Example() a.arr.append(1) print(a.arr)
Es ist sehr wichtig, zwischen den
Attributen einer Klasse und eines Objekts zu unterscheiden . Die Attribute eines Objekts werden PLÖTZLICH aus dem Objekt erstellt.
Es ist wichtig zu verstehen, dass alle im Klassenkörper deklarierten Felder und Methoden zur Klasse gehören. Um ein Attribut für ein Objekt zu erstellen, müssen Sie es dem Objekt in der Klassenmethode über self oder im Programmtext über die Objektvariable zuweisen.
Wenn Sie verwirrt sind, analysieren wir den vorherigen Code. Darin werden zwei Instanzen der Klasse erstellt. Anschließend wird 1 über ein der Objekte zum Feld arr hinzugefügt. Das Objekt enthält jedoch kein solches Attribut. Der Konstruktor ist leer. Daher sucht Python in der Klasse nach diesem Attribut und findet es. Es wird jedoch von allen Instanzen der Klasse gemeinsam genutzt. Sie können überprüfen, ob dies das Attribut der Klasse in der letzten Zeile ist, da der Zugriff auf die Klasse mit dem Namen dieses Attributs keinen Fehler generiert hat.
Beim Erlernen einer neuen Sprache ist es wichtig zu verstehen, dass jede Sprache ihre eigene Philosophie hat und nicht alle Sprachen das statische Schlüsselwort haben sollten. Manchmal wird ein ähnlicher Mechanismus durch andere Mechanismen bereitgestellt.
Am deutlichsten zeigt die Idee, dass Python kein Java ist, dass das Hinzufügen von Feldern in Objekten und Klassen durch die übliche Zuweisung erfolgt:
def make_title(self): if self.title == 'Mister': return 'Mr. ' + self.surname class Person: pass john = Person() john.title = 'Mister' john.name = 'John' john.surname = 'Peterson' john.age = 33 Person.make_title = make_title print(john.make_title())
Allgemeine Empfehlung: Speichern Sie keine veränderlichen Typen als Instanzen einer Klasse. Dies ist jedoch schwierig. Wenn Sie jedoch wissen, was Sie tun, nutzen Sie diese Funktionalität in vollem Umfang. Die Hauptsache ist, am Anfang sorgfältig über alles nachzudenken und danach zu dokumentieren.
Beispielsweise ist es sehr einfach, eine Klasse zu erstellen, in der Links zu allen Instanzen gespeichert sind:
class RememberAll(): instances = [] def __init__(self): self.instances.append(self) a = RememberAll() b = RememberAll() print(RememberAll.instances)
Sie können die Klasse eines physischen Objekts implementieren und beim Ändern seiner Eigenschaften Methoden aufrufen, um die Eigenschaften anderer Elemente des Systems neu zu berechnen. Oder merken Sie sich alle Schieberegler im Formular und verschieben Sie den Rest automatisch, wenn Sie einen verschieben. Ich nehme nicht an zu sagen, dass eine solche Implementierung immer einfach gut ist, aber manchmal kann sie nützlich sein.
Nun, da wir die Physik angesprochen haben, möchte ich den @ -Operator erwähnen. Ja, da
ist einer . Es wurde für die Matrixmultiplikation eingeführt, was am lustigsten ist, aber es scheint, dass es für keinen der Standarddatentypen implementiert wurde, dh es wurde ursprünglich nur für Bibliotheken von Drittanbietern eingeführt. Nichts hindert Sie jedoch daran, die Unterstützung für Ihre Datentypen durch Implementierung der Methoden __matmul__, __rmatmul__, __imatmul__ hinzuzufügen
class Person: def __init__(self, name): self.name = name def __matmul__(self, msg): return "@" + self.name + " " + msg john = Person("John") print(john @ "hello")