[CleanArchitecture mit Python] Wenden Sie CleanArchitecture Schritt für Schritt auf eine einfache API an und versuchen Sie zu verstehen, welche Art von Änderung in der Codebasis stark ist.

Klicken Sie hier, um den endgültigen Beispielcode für Clean Architecture mit Python anzuzeigen: https://github.com/y-tomimoto/CleanArchitecture/tree/master/part9

app
├── application_business_rules
│   ├── __init__.py
│   ├── boundary
│   │   ├── __init__.py
│   │   ├── input_port
│   │   │   ├── __init__.py
│   │   │   └── memo_input_port.py
│   │   └── output_port
│   │       ├── __init__.py
│   │       └── memo_output_port.py
│   └── memo_handle_interactor.py
├── enterprise_business_rules
│   ├── __init__.py
│   ├── dto
│   │   ├── __init__.py
│   │   ├── input_memo_dto.py
│   │   └── output_memo_dto.py
│   ├── entity
│   │   ├── __init__.py
│   │   └── memo.py
│   ├── memo_data.py
│   └── value_object
│       ├── __init__.py
│       └── memo_author.py
├── frameworks_and_drivers
│   ├── __init__.py
│   ├── db
│   │   ├── __init__.py
│   │   ├── mysql.py
│   │   └── postgres.py
│   └── web
│       ├── __init__.py
│       ├── fastapi_router.py
│       └── flask_router.py
├── interface_adapters
│   ├── __init__.py
│   ├── controller
│   │   ├── __init__.py
│   │   └── flask_controller.py
│   ├── gataways
│   │   ├── __init__.py
│   │   └── memo_repository_gateway.py
│   └── presenter
│       ├── __init__.py
│       ├── ad_presenter.py
│       └── default_presenter.py
└── main.py


Zusammenfassung: Wie stark ist die Änderung für jede Schicht, die Sie übernehmen?

Präsentieren Sie jeden Vorteil, der durch die schrittweise Anwendung von Clean Architecture erzielt wird

https___qiita-image-store.s3.amazonaws.com_0_293368_7ce1fb10-504e-16e0-8930-278b8a7f942d.jpeg

Teil 2: Frameworks & Drivers Layer: Die Entstehung des Web

Durch Ausschneiden jedes Webanwendungsframeworks, das Sie in die Ebene Frameworks & Drivers: Web übernehmen möchten, und Ausschneiden der ursprünglich von der Anwendung erwarteten Verarbeitung in "MemoHandler". Durch einfaches Aufrufen des Routers, den Sie mit "main.py" übernehmen möchten, können Sie das Framework ** flexibel ändern, ohne "memo_handler.py" zu ändern. Dies ist der Prozess, den Sie ursprünglich von der Anwendung erwartet hatten. ..

Dieses Design implementiert eine der CleanArchitecture-Regeln, ** Framework Independence **.

Saubere Architektur (übersetzt von The Clean Architecture): https://blog.tai2.net/the_clean_architecture.html

Framework-Unabhängigkeit: Die Architektur ist nicht auf die Verfügbarkeit einer funktionsreichen Softwarebibliothek angewiesen. Dies ermöglicht die Verwendung solcher Frameworks als Werkzeuge und zwingt das System nicht dazu, in die begrenzten Einschränkungen des Frameworks gezwungen zu werden.

Teil 3: Darstellung der Ebene der Unternehmensgeschäftsregeln und der Ebene der Geschäftsregeln für Anwendungen

Memo_handler.py beschreibt die Verarbeitung, die Sie ursprünglich von der Anwendung erwartet hatten

Eingeteilt in.

Dies macht memo_handler.py,

  1. Grundsätzliche Bearbeitung im Antrag und
  2. Verwendung für die Flüssigkeitsverarbeitung, die den Anwendungsspezifikationen entspricht

Durch die Aufteilung in, wenn die Spezifikationen der Anwendung geändert werden, wird sie so konzipiert, dass die Spezifikationen flexibel geändert und erweitert werden können, ohne die bestehende prinzipielle Verarbeitung zu beeinträchtigen.

Teil 4: Schnittstellenadapter-Schicht: Einführung in Controller

Durch Nutzung des Controllers in der Ebene "Schnittstellenadapter" Der Teil der Änderung des häufig aktualisierten "externen Anforderungsformats" in ein Format, das für die tatsächliche Verarbeitung geeignet ist, Ich konnte es aus dem Rahmen herausschneiden.

Auf diese Weise können Sie das Format der Anforderungen ändern, die Ihre Anwendung annehmen kann. Es soll Ihnen ermöglichen, Ihren Code zu ändern, ohne vorhandene Webanwendungsframeworks oder Geschäftsregeln zu berücksichtigen.

Teil 5: ~ Extra Edition ~ Verwendung von DTO

Durch die Einführung von DTO wird der Datenzugriff zwischen Schichten erleichtert und gleichzeitig Es wurde entwickelt, um die Auswirkungen auf jede Schicht zu minimieren, wenn sich die von der Anwendung verarbeitete Datenstruktur ändert.

Teil 6: Schnittstellenadapter Ebene: Präsentator wird angezeigt

Neben der Implementierung von Presenter haben wir auch OutputPort implementiert.

Wenn Sie die Benutzeroberfläche ändern, ist sie daher so konzipiert, dass nur die Benutzeroberfläche unabhängig geändert werden kann, ohne das vorhandene Webanwendungsframework oder die Geschäftsregeln zu berücksichtigen.

Mit der Einführung dieses Präsentators wurden CleanArchitecture-Regeln und die Unabhängigkeit der Benutzeroberfläche erreicht.

Saubere Architektur (übersetzt von The Clean Architecture): https://blog.tai2.net/the_clean_architecture.html

Die Benutzeroberfläche kann leicht geändert werden. Der Rest des Systems muss nicht geändert werden. Beispielsweise kann die Web-Benutzeroberfläche durch die Konsolen-Benutzeroberfläche ersetzt werden, ohne die Geschäftsregeln zu ändern.

Teil 7: Frameworks & Drivers-Ebene: DB- und Schnittstellenadapter-Ebene: Gateways ist hier

Wir haben DB in der DB-Schicht implementiert und Gataways übernommen.

Wenn Sie die Datenbank ändern, ist sie daher so konzipiert, dass die Datenbank ohne Berücksichtigung jeder Schicht umgeschaltet werden kann.

Infolgedessen wurden CleanArchitecture-Regeln und Datenbankunabhängigkeit erreicht.

Saubere Architektur (übersetzt von The Clean Architecture): https://blog.tai2.net/the_clean_architecture.html

Datenbankunabhängig. Sie können Oracle oder SQL Server durch Mongo, BigTable, CoucheDB oder etwas anderes ersetzen. Geschäftsregeln sind nicht an die Datenbank gebunden.

Teil 8: Enterprise Business Rules Layer: Übernahme von Entity & Value Object

Kommunizieren Sie mit der Datenbank über Entity, ein Objekt mit derselben Struktur wie die Datenbank Um streng vertrauliche Eigenschaften zu verbergen, haben wir DTO in jede Geschäftsregel übernommen.

Infolgedessen ist jede Geschäftsregel so konzipiert, dass sie Werte in der Datenbank verarbeiten kann, ohne vertrauliche Eigenschaften zu kennen.

Darüber hinaus wird die Validierung und Verarbeitung jeder Eigenschaft durch die Übernahme von ValueObject von der Entität unabhängig gemacht. Daher ist es beim Erstellen oder Ändern einer Entität nicht mehr erforderlich, sie unter Berücksichtigung bestimmter Eigenschaften zu implementieren.

Warum diesen Artikel schreiben?

Vor kurzem wurde ich einem Projekt zugewiesen, das technisch herausgefordert werden konnte, und so übernahm ich Clean Architecture.

https___qiita-image-store.s3.amazonaws.com_0_293368_7ce1fb10-504e-16e0-8930-278b8a7f942d.jpeg

Ich wollte das, was ich gelernt hatte, als ich ihn anstellte, neu verbalisieren.

Als ich es implementierte, dachte ich, es wäre besser gewesen, wenn es einen Artikel gäbe, der die Probleme erklärt, die jede Schicht in der Codebasis lösen würde.

Ich habe beschlossen, diesen Artikel zu schreiben.

Wie schreibe ich einen Artikel

Wie oben erwähnt, sind die derzeit veröffentlichten Artikel über Clean Architecture Ich persönlich denke, dass es oft aus den folgenden zwei Teilen besteht.

  1. Der Code des von * Clean Architecture erstellten Artefakts sieht folgendermaßen aus. * *
  2. Der Code von * ○○ entspricht der Ebene ○○, und die Ebene ○○ spielt eine solche Rolle. * *

** Bei der Vorstellung, "gegen welche Art von Änderungen die saubere Architektur besonders resistent ist" **

Es ist keine Struktur, die den Code des bereits fertiggestellten Artefakts von Anfang an darstellt

    • Wir werden die Probleme, die bestehende Ergebnisse bei der Änderung von Spezifikationen haben, schrittweise lösen *
    • Die endgültige Konfiguration ist "CleanArchitecture" *

Ich werde es schaffen.

Über die Geschichte jedes Teils

Was ich in diesem Artikel klarstellen möchte, ist

** "Gegen welche Änderungen ist Clean Architecture besonders resistent?" **

ist.

In diesem Artikel werden wir Clean Architecture mit der folgenden Entwicklung anwenden.

Lass uns anfangen.

Inhaltsverzeichnis

[Teil 1: Erstellen einer einfachen Basis-API](https://qiita.com/y_tom/items/ac6f6a08bdc374336dc4#part1-%E3%83%99%E3%83%BC%E3%82%B9%E3 % 81% A8% E3% 81% AA% E3% 82% 8B% E3% 82% B7% E3% 83% B3% E3% 83% 97% E3% 83% AB% E3% 81% AA-api-% E3% 82% 92% E4% BD% 9C% E6% 88% 90% E3% 81% 99% E3% 82% 8B-1)

Teil 2: Frameworks & Drivers Layer: Die Entstehung des Web

Teil 3: Darstellung der Ebene der Unternehmensgeschäftsregeln und der Ebene der Geschäftsregeln für Anwendungen

Teil 4: Schnittstellenadapter-Schicht: Einführung in Controller

Teil 5: ~ Extra Edition ~ Verwendung von DTO

Teil 6: Schnittstellenadapter Ebene: Präsentator wird angezeigt

Teil 7: Frameworks & Drivers-Ebene: DB- und Schnittstellenadapter-Ebene: Gateways ist hier

Teil 8: Enterprise Business Rules Layer: Übernahme von Entity & Value Object

Teil 9: Testbar ~ Zusammenfassung

Teil 1: Erstellen Sie eine einfache Basis-API

In Teil 1 erstellen wir eine API, die die Grundlage für die Erläuterung des folgenden Teils bildet.

Beim Erstellen

Ich habe versucht, diese API so zu implementieren, dass sie absichtlich monolithisch ist, ohne eine Spezifikationsänderung anzunehmen **.

Durch die absichtliche Monolithisierung soll die Visualisierung der Vorteile des Designs bei der Anwendung von CleanArchitecture vereinfacht werden.

Lassen Sie uns in den folgenden Abschnitten beobachten, wie die Datei allmählich durch die Verantwortung geteilt wird und die Kombination allmählich locker wird.

Das erste Ergebnis, bei dem Clean Architecture schrittweise angewendet wird

Diesmal

  1. ** POST-Anfrage erhalten und Notizen speichern **

  2. ** Erhalten Sie eine GET-Anfrage und beziehen Sie sich auf das gespeicherte Memo **

Machen Sie einfach eine Notiz-API.

Implementierung

Verwenden Sie das Webanwendungsframework Flask, um eine einfache API zu erstellen.

1. Bereiten Sie den Endpunkt vor

Ich werde die Anforderungen erneut veröffentlichen, aber die diesmal erstellte API ist

  1. ** POST-Anfrage erhalten und Notizen speichern **
  2. ** Erhalten Sie eine GET-Anfrage und beziehen Sie sich auf das gespeicherte Memo **

ist.

Implementierungen, die die Anforderungen erfüllen, behandeln "memo" mit "memo_id" als Primärschlüssel.

Bereiten Sie zunächst einen Endpunkt vor, der die beiden oben genannten Punkte ausführt.


  1. Verwenden Sie Flask, um einen Endpunkt für den Empfang von POST-Anforderungen und das Speichern von Notizen vorzubereiten.

    from flask import Flask, request
    app = Flask(__name__)
    
    @app.route('/memo/<int:memo_id>', methods=['POST'])
    def post(memo_id: int) -> str:
        #Holen Sie sich Wert von Anfrage
        memo: str = request.form["memo"]
        pass
    
  2. Bereiten Sie auf ähnliche Weise einen Endpunkt für den ** Empfang einer GET-Anforderung und den Verweis auf das gespeicherte Memo ** vor.

    @app.route('/memo/<int:memo_id>')
    def get(memo_id: int) -> str:
        pass
    

2. Bereiten Sie ein Teil für den Notenaustausch mit DB vor

Beschreiben wir nun die Interaktion mit der Datenbank, in der das Memo auf diesem Endpunkt gespeichert ist. Dieses Mal wird MySQL als Datenbank zum Speichern verwendet.


  1. Bereiten Sie zunächst eine Funktion vor, um zu überprüfen, ob in memo_id ein Memo vorhanden ist.

    from mysql import connector
    
    #Einstellungen für die DB-Verbindung
    config = {
        'user': 'root',
        'password': 'password',
        'host': 'mysql',
        'database': 'test_database',
        'autocommit': True
    }
    
    
    def exist(memo_id: int) -> bool:
        #Erstellen Sie einen DB-Client
        conn = connector.connect(**config)
        cursor = conn.cursor()
    
        # memo_Überprüfen Sie, ob eine ID vorhanden ist
        query = "SELECT EXISTS(SELECT * FROM test_table WHERE memo_id = %s)"
        cursor.execute(query, [memo_id])
        result: tuple = cursor.fetchone()
    
        #Schließen Sie den DB-Client
        cursor.close()
        conn.close()
    
        #Überprüfen Sie die Existenz, indem Sie prüfen, ob es ein Suchergebnis gibt
        if result[0] == 1:
            return True
        else:
            return False
    
  2. Fügen Sie als Nächstes die ** Antwort auf die POST-Anforderung hinzu und speichern Sie die Notiz ** zum erstellten Endpunkt.

    from flask import Flask, request, jsonify
    from mysql import connector
    from werkzeug.exceptions import Conflict
    app = Flask(__name__)
    
    @app.route('/memo/<int:memo_id>', methods=['POST'])
    def post(memo_id: int) -> str:
    
        #Überprüfen Sie, ob eine bestimmte ID vorhanden ist
        is_exist: bool = exist(memo_id)
    
        if is_exist:
            raise Conflict(f'memo_id [{memo_id}] is already registered.')
    
        #Holen Sie sich Wert von Anfrage
        memo: str = request.form["memo"]
    
        #Erstellen Sie einen DB-Client
        conn = connector.connect(**config)
        cursor = conn.cursor()
    
        #Memo speichern
        query = "INSERT INTO test_table (memo_id, memo) VALUES (%s, %s)"
        cursor.execute(query, (memo_id, memo))
    
        #Schließen Sie den DB-Client
        cursor.close()
        conn.close()
    
        return jsonify(
            {
                "message": "saved."
            }
        )
    
    

  1. Implementieren Sie als Nächstes den ** Prozess, der die ** GET-Anforderung empfängt und auf das in der externen Datenbank gespeicherte Memo verweist **.

    from werkzeug.exceptions import NotFound
    
    
    @app.route('/memo/<int:memo_id>')
    def get(memo_id: int) -> str:
    
        #Überprüfen Sie, ob eine bestimmte ID vorhanden ist
        is_exist: bool = exist(memo_id)
    
        if not is_exist:
            raise NotFound(f'memo_id [{memo_id}] is not registered yet.')
    
        #Erstellen Sie einen DB-Client
        conn = connector.connect(**config)
        cursor = conn.cursor()
    
        # memo_Führen Sie eine Suche nach ID durch
        query = "SELECT * FROM test_table WHERE memo_id = %s"
        cursor.execute(query, [memo_id])
        result: tuple = cursor.fetchone()
    
        #Schließen Sie den DB-Client
        cursor.close()
        conn.close()
    
        return jsonify(
            {
                "message": f'memo : [{result[1]}]'
            }
        )
    
    
  2. Stellen Sie als Nächstes den Fehlerbehandler ein.

    from http import HTTPStatus
    from flask import make_response
    
    @app.errorhandler(NotFound)
    def handle_404(err):
        json = jsonify(
            {
                "message": err.description
            }
        )
        return make_response(json, HTTPStatus.NOT_FOUND)
    
    
    @app.errorhandler(Conflict)
    def handle_409(err):
        json = jsonify(
            {
                "message": err.description
            }
        )
        return make_response(json, HTTPStatus.CONFLICT)
    

3. Starten Sie die App

Schließlich wird der Vorgang des Startens von "App" mit jedem bisher generierten Router in der Datei beschrieben.

    
   if __name__ == '__main__':
      app.run(debug=True, host='0.0.0.0')

4. Endgültiger Code

main.py

from http import HTTPStatus
from flask import Flask, request, jsonify, make_response
from mysql import connector
from werkzeug.exceptions import Conflict, NotFound

app = Flask(__name__)

#Einstellungen für die DB-Verbindung
config = {
    'user': 'root',
    'password': 'password',
    'host': 'mysql',
    'database': 'test_database',
    'autocommit': True
}


def exist(memo_id: int) -> bool:
    #Erstellen Sie einen DB-Client
    conn = connector.connect(**config)
    cursor = conn.cursor()

    # memo_Überprüfen Sie, ob eine ID vorhanden ist
    query = "SELECT EXISTS(SELECT * FROM test_table WHERE memo_id = %s)"
    cursor.execute(query, [memo_id])
    result: tuple = cursor.fetchone()

    #Schließen Sie den DB-Client
    cursor.close()
    conn.close()

    #Überprüfen Sie die Existenz, indem Sie prüfen, ob es ein Suchergebnis gibt
    if result[0] == 1:
        return True
    else:
        return False


@app.route('/memo/<int:memo_id>')
def get(memo_id: int) -> str:
    #Überprüfen Sie, ob eine bestimmte ID vorhanden ist
    is_exist: bool = exist(memo_id)

    if not is_exist:
        raise NotFound(f'memo_id [{memo_id}] is not registered yet.')

    #Erstellen Sie einen DB-Client
    conn = connector.connect(**config)
    cursor = conn.cursor()

    # memo_Führen Sie eine Suche nach ID durch
    query = "SELECT * FROM test_table WHERE memo_id = %s"
    cursor.execute(query, [memo_id])
    result: tuple = cursor.fetchone()

    #Schließen Sie den DB-Client
    cursor.close()
    conn.close()

    return jsonify(
        {
            "message": f'memo : [{result[1]}]'
        }
    )


@app.route('/memo/<int:memo_id>', methods=['POST'])
def post(memo_id: int) -> str:
    #Überprüfen Sie, ob eine bestimmte ID vorhanden ist
    is_exist: bool = exist(memo_id)

    if is_exist:
        raise Conflict(f'memo_id [{memo_id}] is already registered.')

    #Holen Sie sich Wert von Anfrage
    memo: str = request.form["memo"]

    #Erstellen Sie einen DB-Client
    conn = connector.connect(**config)
    cursor = conn.cursor()

    #Memo speichern
    query = "INSERT INTO test_table (memo_id, memo) VALUES (%s, %s)"
    cursor.execute(query, (memo_id, memo))

    #Schließen Sie den DB-Client
    cursor.close()
    conn.close()

    return jsonify(
        {
            "message": "saved."
        }
    )


@app.errorhandler(NotFound)
def handle_404(err):
    json = jsonify(
        {
            "message": err.description
        }
    )
    return make_response(json, HTTPStatus.NOT_FOUND)


@app.errorhandler(Conflict)
def handle_409(err):
    json = jsonify(
        {
            "message": err.description
        }
    )
    return make_response(json, HTTPStatus.CONFLICT)


if __name__ == '__main__':
    app.run(debug=True, host='0.0.0.0')


Nach Teil 1

Jetzt haben Sie eine API, die die folgenden zwei Dinge ausführt:

  1. ** POST-Anfrage erhalten und Notizen speichern **
  2. ** Erhalten Sie eine GET-Anfrage und beziehen Sie sich auf das gespeicherte Memo **

In den folgenden Artikeln wird für jeden Teil der gesamte Code einschließlich der Containerumgebung im folgenden Repository gespeichert Wenn Sie es zur Hand bewegen möchten, lesen Sie bitte Folgendes.

Part1: https://github.com/y-tomimoto/CleanArchitecture/tree/master/part1

Nehmen wir ab dem nächsten Teil eine Spezifikationsänderungsanforderung für diese API an und wenden Sie die saubere Architektur Schritt für Schritt an.

Recommended Posts

[CleanArchitecture mit Python] Wenden Sie CleanArchitecture Schritt für Schritt auf eine einfache API an und versuchen Sie zu verstehen, welche Art von Änderung in der Codebasis stark ist.
Der Versuch, Segmentbäume Schritt für Schritt zu implementieren und zu verstehen (Python)
[Python] Ich habe versucht, die Texte von Arashi mit WordCloud zu visualisieren und herauszufinden, was ich den Fans in 20 Jahren Ausbildung vermitteln wollte
[Einführung in die Statistik] Welche Art von Verteilung ist die t-Verteilung, die Chi-Quadrat-Verteilung und die F-Verteilung? Eine kleine Zusammenfassung der Verwendung von [Python]
Eine Geschichte über die Portierung des Codes "Versuchen Sie zu verstehen, wie Linux funktioniert" nach Rust
Wenn Sie versuchen, eine Wortwolke mit Kommentaren von WEB-Manga zu erstellen, ist es interessant, visuell zu verstehen, um welche Art von Manga es sich handelt.
[Einführung in Python] Was ist der Unterschied zwischen einer Liste und einem Taple?
Codebeispiel zum Abrufen von oauth_token und oauth_token_secret der Twitter-API in Python 2.7
Was für ein Buch ist der meistverkaufte "Python Crash Course" der Welt?
Liste der in Twitter verwendeten Sprachcodes (einschließlich API) (mit Python-Wörterbuch). Was ist die am häufigsten verwendete Sprache?
Einführung und Verwendung der Python-Flasche ・ Versuchen Sie, einen einfachen Webserver mit Anmeldefunktion einzurichten
[Einführung in Python] Wie wird mit der continue-Anweisung wiederholt?
Versuchen Sie, das Problem des Handlungsreisenden mit einem genetischen Algorithmus (Python-Code) zu lösen.
So erhalten Sie mit Python eine Liste der Dateien im selben Verzeichnis
Verwenden Sie Ruby und Python, um die Wahrscheinlichkeit zu ermitteln, dass eine Karte mit einer natürlichen Zahl von 1 bis 100 ein Vielfaches von 3 und kein Vielfaches von 5 ist.
Eine Einführung in die GUI-Software der Klassenplattform, die mit Python / Tkinter erstellt wurde! (Und viele Try and Error)! (Während des Schreibens)
Verwenden Sie tkinter, um den Ausgabecode in Python als "A und vorgeben, B zu sein" zu verschieben
Automatisieren Sie das Entfernen des Hintergrunds für die neuesten Porträts in einem Verzeichnis mit Python und API
Wie identifiziere ich das Element mit der geringsten Anzahl von Zeichen in einer Python-Liste?
[Python] Ändern Sie die Textfarbe und Hintergrundfarbe eines bestimmten Schlüsselworts in der Druckausgabe
So überprüfen Sie in Python, ob sich eines der Elemente einer Liste in einer anderen Liste befindet
Es ist einfach, SQL mit Python auszuführen und das Ergebnis in Excel auszugeben
Was ist Gott? Erstelle einen einfachen Chatbot mit Python
Notieren Sie sich, was Sie in Zukunft mit Razpai machen möchten
Ich habe eine Klasse erstellt, um das Analyseergebnis von MeCab in ndarray mit Python zu erhalten
Rufen Sie die Excel-Liste rekursiv in einem bestimmten Ordner mit Python ab und schreiben Sie sie in Excel.
Ich habe auch versucht, die Funktionsmonade und die Zustandsmonade mit dem Generator in Python nachzuahmen
Ich schrieb einen Test in "Ich habe versucht, die Wahrscheinlichkeit eines Bingospiels mit Python zu simulieren".
[Python] Was ist ein Tupel? Erklärt, wie man es benutzt und wie man es benutzt, ohne zu tippen.
Versuchen Sie, in die Datenbank zu importieren, indem Sie ShapeFile mit numerischen Informationen zum nationalen Land mit Python bearbeiten
Versuchen Sie, COVID-19 Tokyo-Daten mit Python zu kratzen
Versuchen Sie, mit Python schnell und einfach auf die Twitter-API zuzugreifen
Ändern Sie das Standardausgabeziel in eine Datei in Python
Ich möchte die Effizienz mit Python auch im experimentellen System verbessern. (5) Ich möchte am Ende des Experiments eine Benachrichtigung mit der Slack-API senden
Versuchen Sie, ein Unterfenster mit PyQt5 und Python zu öffnen
Versuchen Sie, den Betrieb von Netzwerkgeräten mit Python zu automatisieren
Versuchen Sie einfach, einen Webhook mit ngrok und Python zu erhalten
[Python] Was ist ein Slice? Eine leicht verständliche Erklärung zur Verwendung anhand eines konkreten Beispiels
Schreiben Sie ein Skript in Shell und Python, um Sie in Slack zu benachrichtigen, wenn der Vorgang abgeschlossen ist
Ich habe versucht, die Sprecheridentifikation mithilfe der Sprechererkennungs-API von Azure Cognitive Services mit Python zu überprüfen. # 1
[Python] Was ist Pip? Erläutern Sie die Befehlsliste und deren Verwendung anhand aktueller Beispiele
Ich habe versucht, die Sprecheridentifikation mithilfe der Sprechererkennungs-API von Azure Cognitive Services in Python zu überprüfen. # 2
Was tun, wenn ein Teil des Hintergrundbilds transparent wird, wenn Sie transparente Bilder mit Pillow kombinieren?
[Python] Die Rolle des Sterns vor der Variablen. Teilen Sie den Eingabewert und weisen Sie ihn einer Variablen zu
Ein einfacher Grund, warum der Rückgabewert von round (2.675,2) in Python 2,67 beträgt (in Wirklichkeit sollte er 2,68 betragen ...)
Erforderliche Mindestkenntnisse beim Umgang mit "Winkeln" und "Koordinaten" in Ruby + In welche Richtung ist Herr B aus der Sicht von Herrn A? Algorithmus
Führen Sie Jupyter mit der REST-API aus, um Python-Code zu extrahieren und zu speichern
So bestimmen Sie die Existenz eines Selenelements in Python
Eine einfache Datenanalyse von Bitcoin, die von CoinMetrics in Python bereitgestellt wird
Rubyist hat versucht, eine einfache API mit Python + Flasche + MySQL zu erstellen
Versuchen Sie, die Thread-Liste der Nachrichten (Abneigung) mit Python zu erhalten.
Geben und meinen Sie die Einschränkungsoption in scipy.optimize.minimize
So überprüfen Sie die Speichergröße einer Variablen in Python
Was ich mit json.dumps in Pythons base64-Codierung süchtig gemacht habe
Erste Python ② Versuchen Sie, Code zu schreiben, während Sie die Funktionen von Python untersuchen
Versuchen Sie, eine Python-Umgebung mit Visual Studio Code & WSL zu erstellen