[PYTHON] Rache der Typen: Rache der Typen

Dieser Artikel wurde von Armin Ronacher ([@mitsuhiko](https: // twitter.)) Am Sonntag, 24. August 2014, nach einer Diskussion der Python-Community verfasst, die stattfand, als der Vorschlag gemacht wurde, Python Typanmerkungen hinzuzufügen. Dies ist eine Übersetzung des Artikels von Herrn com / mitsuhiko)).

Wenn Sie an Typanmerkungen interessiert sind, die Sie in Python 3.5 einführen möchten, lesen Sie bitte die folgenden Informationen.

Ich selbst bin mit dem Typensystem und anderen Sprachen nicht vertraut, daher denke ich, dass es einige nicht übersetzte Teile, Missverständnisse und Fehlübersetzungen gibt. Wenn Sie einen solchen Fehler finden, wäre es hilfreich, wenn Sie uns eine Bearbeitungsanforderung senden könnten.

Tippe Rache

Dies ist Teil 2 über "Python I Want". Basierend auf den jüngsten Diskussionen werden wir das Typensystem von Python ein wenig untersuchen. Ein Teil dieses Artikels bezieht sich auf Vorheriger Artikel über Slot .. Wie im vorherigen Artikel ist dieser Artikel eine Reflexion für zukünftige Sprachdesigner der Sprache Python und wird in die Welt der CPython-Interpreter eintauchen.

Als einer der Python-Programmierer sind Typen etwas knifflig. Typen existieren und verhalten sich unterschiedlich, aber die meiste Zeit werden Sie die Existenz eines Typs nur bemerken, wenn sich der Typ nicht wie beabsichtigt verhält und die Ausnahme oder Ausführung fehlschlägt.

Python war stolz darauf, wie es mit der Eingabe umging. Ich erinnere mich, dass ich vor vielen Jahren eine FAQ in dieser Sprache gelesen habe, in der stand, dass das Tippen von Enten fantastisch war. Das Tippen von Enten ist auch in Bezug auf die Praktikabilität eine ausgezeichnete Lösung, da es fair ist. Es bekämpft im Grunde keine Typsysteme und schränkt nicht ein, was Sie tun möchten, daher implementiert es eine gute API. Die Dinge, die Sie am häufigsten tun, sind in Python sehr einfach.

Die meisten APIs, die ich für Python entwickelt habe, funktionieren nicht in anderen Sprachen. Selbst eine sehr einfache wie die generische Oberfläche von click funktioniert in anderen Sprachen noch nicht. Der Hauptgrund dafür ist, ständig gegen den Schimmel zu kämpfen.

Vor kurzem gab es eine Debatte über das Hinzufügen statischer Typisierung zu Python. Ich bin sicher, der Zug wird den Bahnhof verlassen und weit weg fahren und niemals zurückkommen. Hier sind meine Gedanken darüber, warum ich hoffe, dass Python sich nicht an explizites Tippen anpasst, weil es interessant ist.

Was ist ein Typensystem?

Ein Typsystem ist eine Regel für die Interaktion von Typen. Es gibt sogar ein Gebiet in der Informatik, das sich nur mit dem gesamten Typ befasst. Die Form selbst ist sehr beeindruckend. Es ist jedoch schwierig, Typsysteme zu ignorieren, selbst wenn Sie sich nicht besonders für theoretische Informatik interessieren.

Ich möchte aus zwei Gründen nicht in das Typensystem einsteigen: Der erste Grund ist, dass ich wenig Verständnis für Typsysteme habe. Der zweite Grund ist, dass das Verständnis nicht so wichtig ist, um die logischen Konsequenzen eines Typsystems zu "realisieren". Für mich ist es wichtig, wie sich der Typ verhält, was sich auf das Design der API auswirkt. Betrachten Sie diesen Artikel daher als grundlegende Einführung in eine bessere API aus meinen Wahnvorstellungen und nicht als Einführung in den richtigen Typ.

Ein Typsystem weist viele Merkmale auf, aber das Wichtigste zur Unterscheidung eines Typs ist die Menge an Informationen, die es liefert, wenn versucht wird, ihn zu erklären.

Verwenden wir Python als Beispiel. Python hat Typen. Auf die Frage nach dem Typ der Zahl "42" antwortet Python, dass es sich um einen ganzzahligen Typ handelt. Dies hat viele Auswirkungen und ermöglicht es dem Interpreter, Regeln für die Interaktion von Ganzzahltypen mit anderen Ganzzahltypen zu definieren.

Es gibt jedoch eine Sache, die Python nicht hat. Es ist ein komplexer Typ. Alle Python-Typen sind primitiv. Dies bedeutet im Grunde, dass jeweils nur ein Typ funktioniert. Das Gegenteil des Basistyps ist der Verbund. Von Zeit zu Zeit sehen Sie Python-Verbundtypen in verschiedenen Kontexten.

Der einfachste komplexe Typ, den die meisten Programmiersprachen haben, ist eine Struktur. Python hat keine direkte Struktur, aber es gibt oft Situationen, in denen Sie Ihre eigene Struktur in einer Rallye definieren müssen. Beispielsweise sind Django- und SQLAlchemy-ORM-Modelle im Wesentlichen Strukturen. Die Spalten jeder Datenbank werden durch Python-Deskriptoren dargestellt, die wiederum den Feldern der Struktur entsprechen. Wenn Sie den Primärschlüssel "id" aufrufen und "IntegerField ()" lautet, wird das Modell als zusammengesetzter Typ definiert.

Komplexe Typen sind nicht auf Strukturen beschränkt. Wenn Sie beispielsweise mehrere Ganzzahlen verwenden möchten, verwenden Sie eine Sammlung wie ein Array. Python stellt Listen bereit, und die einzelnen Elemente der Liste können von einem beliebigen Typ sein. Dies steht im Gegensatz zu einer Liste, die durch Angabe eines Typs definiert wird (z. B. eine Liste von Ganzzahltypen).

Man kann sagen, dass eine "Integer-Typ-Liste" keine Liste ist. Sie können argumentieren, dass Sie den Typ herausfinden können, indem Sie diese Liste durchlaufen, aber Sie werden Probleme mit einer leeren Liste haben. Ich kenne den Typ nicht, wenn ich eine elementlose Liste in Python verwende.

Das exakt gleiche Problem in Python wird durch eine Nullreferenz (None) verursacht. Wenn Sie ein Benutzerobjekt an eine Funktion übergeben und dieses Benutzerobjekt "Keine" sein kann, haben Sie keine Ahnung, ob das Argument ein Benutzerobjekt ist.

Gibt es also eine Lösung? Ein explizit typisiertes Array ohne Nullreferenzen. Haskell ist natürlich eine Sprache, die jeder kennt, aber es gibt andere, die nicht unangemessen erscheinen. Zum Beispiel ist Rust eine bekannte Sprache, die weitgehend C ++ ähnelt, aber ein sehr leistungsfähiges Typsystem in seine Tabellen bringt.

Wie sagt man also "Benutzer existiert nicht", wenn es keine Nullreferenzen gibt? Zum Beispiel ist die Antwort in Rust vom Typ Option. "Option " bedeutet entweder "Einige (Benutzer)" oder "Keine". Ersteres ist eine mit Tags versehene Aufzählung, die einen Wert (einen bestimmten Benutzer) umschließt. Nachdem die Variable entweder einen Wert hat oder nicht existiert, wird der gesamte Code, der sich mit der Variablen befasst, nur kompiliert, wenn Sie den Fall "Keine" explizit behandeln.

Ich kann die Zukunft nicht sagen

In der Vergangenheit war die Welt in klar dynamisch typisierte interpretierte Sprachen und vor statisch typisierte kompilierte Sprachen unterteilt. Dies ändert sich mit dem Aufkommen neuer Trends.

Das erste Anzeichen dafür, dass wir uns auf den Weg in dieses unerforschte Gebiet machten, war C #. Es ist eine statisch kompilierte Sprache, und anfangs war sie Java sehr ähnlich. Mit der Verbesserung der Sprache wurden viele neue systembezogene Funktionen hinzugefügt. Am wichtigsten ist die Einführung von Generika, die eine starke Typisierung für Sammlungen, Listen, Wörterbücher usw. bieten, die nicht vom Compiler bereitgestellt werden. Seitdem ist C # in die entgegengesetzte Richtung der statischen Typisierung gegangen, und es ist jetzt möglich, die statische Typisierung für jede einzelne Variable zu beenden und sie dynamisch zu typisieren. Das ist lächerlich praktisch. Dies gilt insbesondere im Zusammenhang mit der Arbeit mit Daten, die von Webdiensten (JSON, XML usw.) bereitgestellt werden. Mit der dynamischen Eingabe können Sie versuchen, etwas zu tun, das möglicherweise nicht typsicher ist, einen Tippfehler aufgrund falscher Eingabedaten abfangen und dem Benutzer anzeigen.

Heutige C # -Systeme verfügen über sehr starke Generika für die Spezifikationen für Co-Modifikation und Anti-Degeneration. Darüber hinaus wurde auch eine Unterstützung auf Sprachebene für den Umgang mit nullbaren Typen entwickelt. Beispielsweise wurde der Null-Koaleszenzoperator (??) eingeführt, um Standardwerte für Objekte bereitzustellen, die als Null dargestellt werden. C # ist zu spät gekommen, um "null" aus der Sprache zu entfernen, aber es ermöglicht Ihnen, den durch "null" verursachten Schaden zu kontrollieren.

Gleichzeitig erforschen andere Sprachen, die traditionell statisch vorkompiliert sind, auch neue Bereiche. C ++ wird immer statisch typisiert, wird jedoch auf vielen Ebenen immer noch für die Typinferenz berücksichtigt. Die Zeiten von "MyType <X, Y> <:: const_iterator iter" sind vorbei. Heutzutage führt das einfache Ersetzen des Typs durch "auto" in den meisten Situationen dazu, dass der Compiler stattdessen den Typ einbettet.

Rust als Sprache unterstützt auch eine gute Typinferenz, um statisch typisierte Programme ohne völlig willkürliche Typdefinition zu schreiben.

Rust


    use std::collections::HashMap;
    
    fn main() {
        let mut m = HashMap::new();
        m.insert("foo", vec!["some", "tags", "here"]);
        m.insert("bar", vec!["more", "here"]);
    
        for (key, values) in m.iter() {
            println!("{} = {}", key, values.connect("; "));
        }
    }

Ich denke, wir gehen mit einem leistungsstarken Typensystem in die Zukunft. Ich denke nicht, dass dies das Ende der dynamischen Typisierung sein wird, aber es scheint eine deutliche Tendenz zu bestehen, eine starke statische Typisierung mit lokaler Typinferenz zu akzeptieren.

Explizit mit Python getippt

Vor nicht allzu langer Zeit hat jemand die Menschen auf Konferenzen davon überzeugt, dass statisches Tippen eine großartige Sprachfunktion sein sollte. Ich weiß nicht genau, was das Argument war, aber das Endergebnis wurde deklariert, dass die Kombination aus dem Typmodul von mypy und der Typanmerkungssyntax von Python 3 zum Standard für die Eingabe in Python werden würde.

Wenn Sie den Vorschlag noch nicht gesehen haben, wurde Folgendes vorgeschlagen:

Python3


    from typing import List
    
    def print_all_usernames(users: List[User]) -> None:
        for user in users:
            print(user.username)

Um ehrlich zu sein, denke ich, dass dies aus vielen Gründen überhaupt keine gute Entscheidung ist. Der Hauptgrund dafür ist, dass Python unter einem nicht guten Typsystem leidet. Die Bedeutung dieser Sprache hängt davon ab, wie Sie sie betrachten.

Damit statische Typisierung sinnvoll ist, muss das Typensystem gut sein. Bei zwei Typen handelt es sich um ein Typsystem, mit dem Sie wissen, wie sich die Typen zueinander verhalten. Python nicht.

Python-Semantik

Wenn Sie den Artikel über das Slot-System lesen, das ich zuvor geschrieben habe, werden Sie sich daran erinnern, dass Python-Typen unterschiedliche Bedeutungen haben, je nachdem, ob sie auf der Seite der C-Sprache oder der Python-Seite implementiert sind. Dies ist ein ziemlich ungewöhnliches Merkmal dieser Sprache und wird normalerweise in vielen anderen Sprachen nicht gefunden. Es ist richtig, dass in vielen Sprachen Typen auf Interpretationsebene für Bootstrap-Zwecke implementiert sind, diese werden jedoch normalerweise als Basistypen betrachtet und speziell behandelt.

Python hat keinen echten "fundamentalen" Typ. Es gibt jedoch einige Typen, die auf der Seite der C-Sprache implementiert sind. Diese sind überhaupt nicht auf Grundelemente oder Grundtypen beschränkt, sie erscheinen überall ohne Logik. Beispielsweise ist "collection.OrderedDict" ein Typ, der auf der Python-Seite implementiert ist, während "collection.defaultdict" im selben Modul ein Typ ist, der auf der Seite der C-Sprache implementiert ist.

Dies verursacht tatsächlich einige Probleme mit PyPy. Dies liegt daran, dass wir den ursprünglichen Typ so weit wie möglich nachahmen müssen, um eine ähnliche API zu erzielen, bei der diese Unterschiede nicht erkennbar sind. Es ist sehr wichtig zu verstehen, was dieser verschiedene Unterschied zwischen dem Code des C-Sprachniveau-Interpreters und dem Rest der Sprache bedeutet.

Lassen Sie uns als Beispiel auf das Modul "re" bis Python 2.7 hinweisen. (Dieses Verhalten hat sich letztendlich im "re" -Modul geändert, aber es gibt immer noch verschiedene Probleme mit Dolmetschern, die außerhalb der Sprache arbeiten.)

Das Modul "re" bietet die Möglichkeit, einen regulären Ausdruck in ein Muster für reguläre Ausdrücke ("compile") zu kompilieren. Es nimmt eine Zeichenfolge und gibt ein Musterobjekt zurück. Es sieht aus wie das:

Python2.7


    >>> re.compile('foobar')
    <_sre.SRE_Pattern object at 0x1089926b8>

Wie Sie sehen können, befindet sich dieses Musterobjekt im Modul _sre, kann jedoch universell verwendet werden:

Python2.7


    >>> type(re.compile('foobar'))
    <type '_sre.SRE_Pattern'>

Leider war es eine kleine Lüge. Das _sre Modul enthält diesen Typ nicht wirklich.

Python2.7


    >>> import _sre
    >>> _sre.SRE_Pattern
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    AttributeError: 'module' object has no attribute 'SRE_Pattern'

Ja, das ist richtig. Es ist nicht das erste Mal zu lügen, wenn der Typ nicht da ist, und auf jeden Fall ist es ein interner Typ. Fahren Sie also mit dem nächsten fort. Wir wissen, dass der Typ dieses Musterobjekts "_sre.SRE_Pattern" ist. Es ist selbst eine Unterklasse von "Objekt": "

Python2.7


    >>> isinstance(re.compile(''), object)
    True

Wie wir wissen, implementieren alle Objekte einige gemeinsame Methoden. Beispielsweise implementieren alle Objekte "repr".

Python2.7


    >>> re.compile('').__repr__()
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    AttributeError: __repr__

Ahh. Was zur Hölle ist passiert? Nun, die Antwort ist ziemlich komisch. Ich weiß nicht warum, aber intern hatte das SRE-Musterobjekt einen benutzerdefinierten tp_getattr-Slot bis Python 2.7. Dieser Slot hatte einen benutzerdefinierten Attributerkennungsprozess, der den Zugriff auf benutzerdefinierte Methoden und Attribute ermöglichte. Wenn Sie das Objekt tatsächlich mit dir () betrachten, werden Sie feststellen, dass viele Funktionen fehlen.

Python2.7


    >>> dir(re.compile(''))
    ['__copy__', '__deepcopy__', 'findall', 'finditer', 'match',
     'scanner', 'search', 'split', 'sub', 'subn']

Darüber hinaus lädt die Funktionsweise dieses Typs zu einem wirklich seltsamen Abenteuer ein. Hier ist was los ist.

Der Typ Typ behauptet, dass es sich um eine Unterklasse von "Objekt" handelt. Dies gilt in der Welt der CPython-Interpreter, nicht jedoch in der Sprache Python. Es ist eine Schande, dass dies nicht dasselbe ist, aber es ist ein häufiger Fall. Der Typ entspricht nicht der Objektschnittstelle auf der Python-Ebene. Aufrufe über den Interpreter funktionieren, aber Aufrufe über die Python-Sprache schlagen fehl. Das heißt, type (x) ist erfolgreich, während x .__ class__ fehlschlägt.

Was ist eine Unterklasse?

Das obige Beispiel zeigt, dass Python eine andere Unterklasse haben kann, die nicht dem Verhalten der Basisklasse entspricht. Dies ist besonders problematisch, wenn es um statische Typisierung geht. In Python 3 können Sie beispielsweise eine Schnittstelle vom Typ "dict" nur implementieren, wenn Sie den Typ auf der Seite der C-Sprache schreiben. Der Grund ist, dass der Typ ein bestimmtes Verhalten des Ansichtsobjekts garantiert, das nicht einfach zu implementieren ist. Was meinst du?

Wenn Sie eine Funktion statisch kommentieren, die ein Wörterbuch mit Zeichenfolgenschlüsseln und ganzzahligen Objekten empfängt, ist daher nicht ganz klar, ob es sich um ein Objekt wie dict oder dict handelt oder ob es Unterklassen des Wörterbuchs zulässt.

Undefiniertes Verhalten

Das seltsame Verhalten des vorherigen Musterobjekts hat sich in Python 2.7 geändert, das zugrunde liegende Problem bleibt jedoch bestehen. Wie das zuvor erwähnte Verhalten der Diktierinstanz verhält sich die Sprache je nach Schreibweise des Codes unterschiedlich. Und es ist unmöglich, die strenge Bedeutung von Typsystemen vollständig zu verstehen.

Ein sehr seltsamer Fall in einem solchen Interpreter ist der Typvergleich, beispielsweise in Python 2. Dieser spezielle Fall existiert in Python 3 aufgrund von Änderungen an der Benutzeroberfläche nicht, aber das Grundproblem kann auf verschiedenen Ebenen gefunden werden.

Nehmen wir als Beispiel eine Sortierung vom Typ Set. Pythons Set-Typ ist nützlich, aber die Vergleichsoperation ist ziemlich seltsam. In Python 2 gibt es eine Funktion namens "cmp ()", die eine Zahl zurückgibt, die angibt, welcher der beiden angegebenen Typen größer ist. Werte kleiner als 0 bedeuten, dass das erste Argument kleiner als das zweite Argument ist. 0 bedeutet, dass sie gleich sind. Positive Zahlen bedeuten, dass das zweite Argument größer als das erste Argument ist.

Folgendes passiert beim Vergleichen von Sets:

Python2.7


    >>> cmp(set(), set())
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: cannot compare sets using cmp()

Warum? Ich weiß ehrlich gesagt nicht genau. Wahrscheinlich, weil der Vergleichsoperator die Teilmenge tatsächlich setzt und sie nicht mit cmp () funktioniert. Aber zum Beispiel funktioniert der Frozenset-Typ.

Python2.7


    >>> cmp(frozenset(), frozenset())
    0

Es schlägt fehl, wenn einer dieser eingefrorenen Sätze nicht leer ist. Ich wundere mich warum? Die Antwort darauf ist, dass es sich um eine Optimierung des CPython-Interpreters handelt, nicht um eine Sprachfunktion. Frozenset-Praktikanten haben einen gemeinsamen Wert. Ein leeres Frozenset hat immer den gleichen Wert (es ist unveränderlich und kann nicht hinzugefügt werden), daher ist ein leeres Frozenset das gleiche Objekt. Wenn zwei Objekte dieselbe Zeigeradresse haben, gibt "cmp" normalerweise "0" zurück. Aufgrund der komplexen Vergleichslogik in Python 2 verstehe ich nicht sofort, warum dies geschieht, aber es gibt mehrere Codepfade in der Vergleichsroutine, die dieses Ergebnis verursachen können.

Der Punkt ist, dass Python nicht wirklich ein Fehler ist, sondern nicht wirklich die Bedeutung der Interaktion von Typen hat. Das Verhalten des Typsystems war lange Zeit "CPython ausgeliefert".

In PyPy finden Sie eine Vielzahl von Änderungssätzen, die versucht haben, das Verhalten von CPython zu rekonstruieren. Angesichts der Tatsache, dass PyPy in Python geschrieben ist, ist es ein sehr interessantes Thema für die Sprache. Hätte die Sprache Python das Verhalten des Python-Teils der Sprache vollständig definiert, hätte PyPy weitaus weniger Probleme gehabt.

Verhalten auf Instanzebene

Nehmen wir an, Sie haben einen virtuellen Python, der alle oben genannten Probleme behebt. Die statische Eingabe passt jedoch nicht gut zu Python. Der Hauptgrund ist, dass Typen auf der Python-Sprachebene traditionell wenig Bedeutung haben, wenn es darum geht, wie Objekte interagieren.

Beispielsweise kann ein Datum / Uhrzeit-Objekt im Allgemeinen mit anderen Objekten verglichen werden, die Zeitzoneneinstellungen müssen jedoch beim Vergleich mit anderen Datum / Uhrzeit-Objekten kompatibel sein. In ähnlicher Weise sind die Ergebnisse vieler Operationen erst sichtbar, wenn die Hand das Objekt untersucht. Durch Kombinieren der beiden Zeichenfolgen in Python 2 wird entweder ein Unicode- oder ein Bytestring-Objekt erstellt. Die Codierungs- und Decodierungs-API des Codec-Systems gibt jedes Objekt zurück.

Python als Sprache ist zu dynamisch, um mit Anmerkungen zu arbeiten. Überlegen Sie, wie wichtig Generatoren für Ihre Sprache sind. Der Generator kann jedoch mit jeder Iteration unterschiedliche Typkonvertierungen durchführen.

Typanmerkungen können teilweise gut sein, sie können sich jedoch negativ auf das API-Design auswirken. Sofern Sie die Typanmerkung nicht zur Laufzeit entfernen, ist sie zumindest langsam. Wenn Sie Python nicht in etwas anderes als Python verwandelt haben, können Sie niemals eine Sprache implementieren, die effizient und statisch kompiliert werden kann.

Was wurde erhalten und die Theorie der Bedeutung

Was ich persönlich von Python denke, ist, dass Sprachen lächerlich komplex sind. Python ist eine Sprache, die unter diesen komplexen Wechselwirkungen zwischen verschiedenen Typen ohne Sprachspezifikation leidet. Es scheint, dass es niemals zusammenkommen wird. Es gibt so viele mysteriöse und etwas seltsame Verhaltensweisen, dass Sie beim Erstellen einer Sprachspezifikation nur eine Abschrift des CPython-Interpreters erhalten.

Ich denke, es macht wenig Sinn, Typanmerkungen auf diese Grundlage zu setzen.

Wenn in Zukunft jemand eine andere dynamisch typisierte Sprache entwickelt, sollten mehr Anstrengungen unternommen werden, um klar zu definieren, wie Typen funktionieren. JavaScript macht sich in dieser Hinsicht ziemlich gut. Alle seltsamen, aber eingebauten Semantiken sind klar definiert. Ich denke, das ist im Allgemeinen eine gute Sache. Sobald Sie eine klare Definition der Funktionsweise dieser Semantik haben, können Sie sie optimieren oder später optional statisch eingeben.

Es lohnt sich, die Sprache schlank und klar zu halten. Zukünftige Sprachdesigner sollten niemals die Fehler machen, die PHP, Python oder Ruby gemacht haben. Dort endet es mit der Schlussfolgerung, dass das Verhalten der Sprache "dem Dolmetscher ausgeliefert" ist.

Was ich über Python denke, wird sich an dieser Stelle wahrscheinlich nicht ändern. Die Zeit und Mühe, die Sprache und die Dolmetscher zu bereinigen, überwiegt den Wert, den Sie erhalten.

© Copyright 2014 by Armin Ronacher. Content licensed under the Creative Commons attribution-noncommercial-sharealike License.

Recommended Posts

Rache der Typen: Rache der Typen
Der Beginn von cif2cell
Die Bedeutung des Selbst
Arten der Kommunikation zwischen Prozessen
der Zen von Python
Die Geschichte von sys.path.append ()
Was ist ein empfohlener Motor? Zusammenfassung der Typen
Richten Sie die Version von chromedriver_binary aus
Scraping das Ergebnis von "Schedule-Kun"
10. Zählen der Anzahl der Zeilen
Die Geschichte des Baus von Zabbix 4.4
Auf dem Weg zum Ruhestand von Python2
Fangen Sie mehrere Arten von Ausnahmen ab
Vergleichen Sie die Schriftarten von Jupyter-Themen
Holen Sie sich die Anzahl der Ziffern
Erläutern Sie den Code von Tensorflow_in_ROS
Zusammenfassung der Linux-Verteilungstypen
Verwenden Sie die Clustering-Ergebnisse erneut
GoPiGo3 des alten Mannes
Ändern Sie das Thema von Jupyter
Die Popularität von Programmiersprachen
Ändern Sie den Stil von matplotlib
Visualisieren Sie die Flugbahn von Hayabusa 2
Über die Komponenten von Luigi
Verknüpfte Komponenten des Diagramms
Filtern Sie die Ausgabe von tracemalloc
Über die Funktionen von Python
Simulation des Inhalts der Brieftasche
Die Kraft der Pandas: Python
Die Spezifikationen von Pytz haben sich geändert
Testen Sie die Version des Argparse-Moduls
Finden Sie die Definition des Wertes von errno
Der Tag des Dockerlaufs (Hinweis)
Zeichnen Sie die Ausbreitung des neuen Koronavirus
Die Geschichte von Python und die Geschichte von NaN
Erhöhen Sie die Version von pyenv selbst
Holen Sie sich die Anzahl der Ansichten von Qiita
[Python] Der Stolperstein des Imports
Ich habe 11 Arten von Betriebssystemen zusammengefasst
Erster Python 3 ~ Der Beginn der Wiederholung ~
Japanische Übersetzung des e2fsprogs-Handbuchs
Die Geschichte der Teilnahme an AtCoder
Ist die Niederschlagswahrscheinlichkeit korrekt?
Ich habe den Mechanismus der Flaschenanmeldung untersucht!
Verstehen Sie den Inhalt der sklearn-Pipeline
Die Welt der Bücher der Steuerungstechnik
Nimm das Ausführungsprotokoll von Sellerie
Testen Sie die Eignung der Verteilung
Existenz aus Sicht von Python
Berechnung der Anzahl der Assoziationen von Klamer
pyenv-change die Python-Version von virtualenv
Über den Rückgabewert von pthread_mutex_init ()
Ruft die Attribute eines Objekts ab
Lösen Sie die Verzögerung der Interferometerbeobachtung
Diskriminierung der Agari-Form von Mahjong
Python-Simulation des Epidemiemodells (Kermack-McKendrick-Modell)