Ich denke, es gibt viele Situationen, in denen JSON analysiert wird, wenn APIs mit externen Diensten in Python verknüpft werden. Perth ist langweilig und Sie möchten nicht zu viel Zeit in Situationen wie Hackerson verbringen, in denen Geschwindigkeit besonders wichtig ist. Dieses Mal werde ich Ihnen zeigen, wie Sie JSON einfach in eine Python-Datenklasse konvertieren können.
Der in diesem Artikel vorgestellte Code ist auf GitHub verfügbar. https://github.com/gaiax/quicktype-dacite-demo
Wie der Titel schon sagt, verwenden wir hauptsächlich die Bibliotheken quicktype und dacite.
quicktype Eine Bibliothek, die den Typ der Beispieldaten wie JSON ableitet und in der entsprechenden Sprache ausgibt. https://github.com/quicktype/quicktype
Obwohl es als npm-Paket veröffentlicht wurde, kann es auch problemlos als Web-Benutzeroberfläche verwendet werden. Selbst wenn es sich um eine Web-Benutzeroberfläche handelt, wird der Vorgang auf dem Client abgeschlossen, ohne den Server zu durchlaufen. [^ 1] Es ist unter https://app.quicktype.io/ verfügbar.
dacite Eine Bibliothek, die Python-Dikte in Datenklassen konvertiert. https://github.com/konradhalas/dacite
Normalerweise sollte dies bei der Konvertierung von Diktat in Datenklasse der Fall sein.
from dataclasses import dataclass
@dataclass
class Data:
hoge: int
fuga: str
d = {"hoge": 10, "fuga": "Python"}
Data(**d)
# Data(hoge=10, fuga='Python')
Dies funktioniert gut, aber nicht gut mit verschachtelten Wörterbüchern.
from dataclasses import dataclass
@dataclass
class NestedData:
foo: int
bar: str
@dataclass
class Data:
hoge: int
fuga: str
nested_data: NestedData
d = {
"hoge": 10,
"fuga": "Python",
"nested_data": {
"foo": 20,
"bar": "Ruby"
}
}
Data(**d)
# Data(hoge=10, fuga='Python', nested_data={'foo': 20, 'bar': 'Ruby'})
# nested_data ist keine NestedData-Klasse, sondern nur ein Wörterbuch
Dacite ermöglicht solche normalerweise nicht unterstützten verschachtelten Wörterbuchkonvertierungen.
from dataclasses import dataclass
from dacite import from_dict
@dataclass
class NestedData:
foo: int
bar: str
@dataclass
class Data:
hoge: int
fuga: str
nested_data: NestedData
d = {
"hoge": 10,
"fuga": "Python",
"nested_data": {
"foo": 20,
"bar": "Ruby"
}
}
from_dict(data_class=Data, data=d)
# Data(hoge=10, fuga='Python', nested_data=NestedData(foo=20, bar='Ruby'))
# nested_Daten enthalten eine Instanz der NestedData-Klasse!
Es macht es sehr einfach, Wörterbücher und Datenklassen zu konvertieren. Darüber hinaus gibt es zum Zeitpunkt des Schreibens des Artikels (2020/06/10) die folgenden Funktionen.
--Typprüfung
Übrigens ist die Konvertierung von Datenklasse in Wörterbuch möglich, indem eine Instanz von Datenklasse an dataclasses.asdict
in der Python-Standardbibliothek übergeben wird.
Da einige von Ihnen möglicherweise bereits ein Implementierungsimage aus der bisherigen Erklärung erstellt haben, versuchen wir tatsächlich, JSON und Datenklasse aus der Definition der Datenklasse zu konvertieren. Lassen Sie uns als Beispiel den Rückgabewert der Ereignis-API von connpass in eine Datenklasse konvertieren.
Wir sind eine Gruppe namens "Gaiax Technical Meetups" von connpass, die einführende praktische Treffen und Austauschmeetings für Ingenieure abhält. ~~ Plötzliche Werbung ~~ Dieses Mal konzentriert sich die API auf diese Gruppe und bereitet die Daten vor.
Um das Lesen des Artikels zu vereinfachen, beschränken wir die Anzahl der Ereignisse auf zwei.
GET https://connpass.com/api/v1/event/?series_id=3109&count=2
connpass.json
{
"results_start": 1,
"results_returned": 2,
"results_available": 35,
"events": [
{
"event_id": 175102,
"title": "[Online-Dialog] Google Apps Script-Nutzungsgespräch#6",
"catch": "Online-Dialog mit den neuesten Informationen und Anwendungsfällen von Google Apps Script",
"description": "<h1>Kampagne zur Erreichung des Zielbetrags der GAS-Buch-Cloud-Finanzierung!</h1>\n<p>Herr Takahashi von Plan Notes, der Autor von "Vollständige Einführung in Google Apps Script", dem es gelungen ist, "Ich möchte der Welt die neueste" Vollständige Einführung in Google Apps Script "so schnell wie möglich zur Verfügung stellen!" Wird auf der Bühne stehen.<br>\n<a href=\"https://camp-fire.jp/projects/view/249472\" rel=\"nofollow\">https://camp-fire.jp/projects/view/249472</a></p>\n<p>Um das Erreichen des Zielbetrags zu feiern, werden wir die erste Ausgabe von "Google Apps Script Complete Introduction" 5 Personen per Lotterie von den Veranstaltungsteilnehmern als auf diese Veranstaltung beschränkte Kampagne präsentieren! !! !!</p>\n<h1>Detail</h1>\n<p>Die 6. Ausgabe des "Google Apps Script Utilization Meetup", das zu einem beliebten und Standardelement im Technical Meetup geworden ist, findet statt, während das Format geändert wird!</p>\n<p>Die G Suite (Google Apps) von Google wird zunehmend von vielen Unternehmen verwendet. Einführung in die neuesten Informationen und Anwendungsbeispiele von Google Apps Script, einer Skriptsprache, die G Suite erweitert!</p>\n<p>IT-Unternehmen migrieren von Office-Software, die direkt auf ihren PCs installiert ist, zu G Suite, einer Office-Software vom Typ Webanwendung. Es können mehrere Personen gleichzeitig bearbeiten, Dateien werden automatisch in der Cloud gespeichert und es gibt viele Funktionen, die den heute erforderlichen Arbeitsstil unterstützen.</p>\n<p>Google Apps Script erweitert die Funktionalität von G Suite. Da es auf der JavaScript-Sprache basiert, die vielen Menschen vertraut ist, ist seine Geschichte kurz, aber seine Anwendungsfälle nehmen rapide zu.</p>\n<p>※Referenz</p>\n<p>Bitte sehen Sie die vergangenen Ereignisse von der URL unten!</p>\n<p><a href=\"http://gaiax.hatenablog.com/archive\" rel=\"nofollow\">http://gaiax.hatenablog.com/archive</a></p>\n<h1>Zeitplan</h1>\n<ul>\n<li>19:15 Lieferbeginn</li>\n<li>19:30 Gespräch beginnen</li>\n<li>20:30 Fragen und Antworten</li>\n<li>20:50 Fragebogen</li>\n<li>21:00 geschlossen</li>\n</ul>\n<h1>Geplantes Gespräch</h1>\n<h3>Herr Nobunari Takahashi, stellvertretender Direktor von Plan Notes Co., Ltd.</h3>\n<p>Nach seinem Abschluss an der Forschungsabteilung für elektronische Informatik der Universität für Telekommunikation arbeitete er bis zu seinem 30. Lebensjahr als Saxophonist und war als Produzent und Vermarkter in der Branche für mobile Inhalte und elektronische Bücher tätig. Er machte sich 2015 selbstständig, weil er Probleme mit dem Arbeitsstil, der Produktivität und der IT-Auslastung von Geschäftsleuten in Japan hatte. Excel,VBA,GSuite,GAS,Arbeitete an der Entwicklung, Beratung, Schulung, dem Schreiben usw. von Systemwerkzeugen mithilfe der Cloud.\n Trainer des Online-Lerndienstes "Linked In Learning",Vorsitzender der Community "Skill Up Study Group für Nicht-Programmierer".\n Ein Blog von mir<a href=\"https://tonari-it.com/\" rel=\"nofollow\">"Immer ein IT-Job nebenan"</a>Bietet eine monatliche Beliebtheit von 960.000 PV.</p>\n<h3>Geschäftsbereich Social Media Solutions von Gaiax Co., Ltd. Shogo Matsushita</h3>\n<p>Geboren 1995 Geboren in der Präfektur Kanagawa. Rollenspiel Tsukuru und Click in der Junior High School&Treffen Sie Create und öffnen Sie die Tore der Programmierung durch Spielprogrammierung. Danach melden Sie sich am Yokohama Medical Information College an. Während des Schulbesuchs als Praktikant an verschiedenen Orten in der Entwicklung von Webdiensten tätig. Kam 2018 zu Gaiax. Derzeit schreibt er neben Entwicklung und Videoproduktion technische Doujinshi- und Doujin-Videoproduktion in der Abteilung Social Media Marketing.</p>\n<p>Kürzlich veröffentlichte ein Doujinshi über AppMaker</p>\n<ul>\n<li>Booth <a href=\"https://godan.booth.pm/items/2035726\" rel=\"nofollow\">https://godan.booth.pm/items/2035726</a></li>\n<li>bookwalker <a href=\"https://bookwalker.jp/de809d7a5b-1b32-4973-a3d6-61019cf222f2/\" rel=\"nofollow\">https://bookwalker.jp/de809d7a5b-1b32-4973-a3d6-61019cf222f2/</a></li>\n</ul>\n<h1>Vorsichtsmaßnahmen</h1>\n<p>Der Zweck dieser Veranstaltung ist es, das Know-how der Ingenieure zu teilen, und wir akzeptieren keine Teilnahme nur zum Zweck des Essens und Trinkens. Aus diesem Grund bitten wir Sie, an der Rezeption Visitenkarten auszutauschen, um Ihre Identität zu bestätigen. Danke für Ihre Kooperation.</p>\n<p>In Bezug auf Rekrutierungs-LT akzeptieren wir keine Gespräche, die LT enthalten, die nicht mit dem Thema zusammenhängen, und übermäßige Werbung, die nicht zum Thema dieser Veranstaltung passt (ausgenommen Googles G Suite).</p>\n<p>Auf der Konferenz für alle Teilnehmer, die auf der Bühne stehen oder teilnehmen werden<a href=\"http://ja.confcodeofconduct.com/\" rel=\"nofollow\">Verhaltensregeln(Conference Code of Conduct) </a>Bitte beachten Sie. Bitte beachten Sie, dass wir alle Maßnahmen ergreifen werden, einschließlich der Entlassung aus der Veranstaltung, wenn die Event-Management-Seite feststellt, dass es sich um eine schwerwiegende Belästigung handelt.</p>",
"event_url": "https://gaiax.connpass.com/event/175102/",
"started_at": "2020-05-29T19:30:00+09:00",
"ended_at": "2020-05-29T22:00:00+09:00",
"limit": null,
"hash_tag": "GAS-Aktivität",
"event_type": "participation",
"accepted": 45,
"waiting": 0,
"updated_at": "2020-05-08T14:09:19+09:00",
"owner_id": 28874,
"owner_nickname": "xtetsuji",
"owner_display_name": "OGATA Tetsuji",
"place": "online",
"address": "online",
"lat": null,
"lon": null,
"series": {
"id": 3109,
"title": "Gaiax Technical Meetups",
"url": "https://gaiax.connpass.com/"
}
},
{
"event_id": 173835,
"title": "[Für Anfänger] Einführung in Flutter Online Hands-on",
"catch": "Praktische Veranstaltung für diejenigen, die Flutter berühren möchten",
"description": "<h1>Über Online halten</h1>\n<p>Dieses Mal wird es online stattfinden. Am Tag der Veranstaltung senden wir Ihnen die Online-Teilnahme-URL per E-Mail.</p>\n<h1>Detail</h1>\n<p>iPhone/Flattern, mit dem Sie Andriod-Apps in einer Umgebung entwickeln können. Obwohl die Zahl der Fälle nach und nach zugenommen hat, gibt es meines Erachtens viele Menschen, die dies noch nicht angesprochen haben.</p>\n<p>Daher erklären Ingenieure, die mit Flutter native Apps entwickeln und veröffentlichen, wie man einfache Anwendungen für Anfänger erstellt, wobei der Schwerpunkt auf Live-Codierung liegt!</p>\n<p>※Referenz</p>\n<p>Bitte sehen Sie die vergangenen Ereignisse von der URL unten!</p>\n<p><a href=\"http://gaiax.hatenablog.com/archive\" rel=\"nofollow\">http://gaiax.hatenablog.com/archive</a></p>\n<h1>Bitte machen Sie mit, wenn Ihnen das gefällt</h1>\n<ul>\n<li>Ich bin daran interessiert, Flutter zu kennen (ich habe davon gehört)</li>\n<li>iPhone/Interessiert an Android-Entwicklung</li>\n<li>Swift /Ich habe Entwicklungserfahrung mit Kotlin und möchte Flutter kennenlernen</li>\n<li>Haben Sie einige Entwicklungserfahrung wie WEB-Service</li>\n</ul>\n<h1>Zeitplan</h1>\n<ul>\n<li>19:15 Empfang</li>\n<li>19:30 Hände am Start</li>\n<li>21:30 Fragebogen</li>\n</ul>\n<h1>Was die Teilnehmer vorbereiten sollen</h1>\n<ul>\n<li>Diejenigen, die ihre Hände zusammen bewegen wollen<ul>\n<li>Bitte bereiten Sie die Umgebung vor, indem Sie auf den folgenden Qiita-Artikel usw. verweisen.</li>\n<li><a href=\"https://qiita.com/tomy0610/items/896dc8ec9ba95c33194f\" rel=\"nofollow\">https://qiita.com/tomy0610/items/896dc8ec9ba95c33194f</a></li>\n</ul>\n</li>\n</ul>\n<h1>Erforderliche Erfahrung / Fähigkeiten</h1>\n<p>Es richtet sich an Personen mit Entwicklungserfahrung.\n Es gibt keine Erklärung für die Erstellung einer Entwicklungsumgebung, einer Programmiersprache oder eines grundlegenden Mechanismus.</p>\n<h1>Vorsichtsmaßnahmen</h1>\n<p>Der Zweck dieser Veranstaltung ist es, das Know-how der Ingenieure zu teilen, und wir akzeptieren keine Gespräche, die LT beinhalten, die nicht mit dem Thema zusammenhängen, oder übermäßige Werbung, die nicht zum Thema dieser Veranstaltung passt.</p>\n<p>Bitte beachten Sie, dass wir es als Material wie Fotos und Videos der Holding-Szenerie verwenden, um den Veranstaltungsbericht in Blogs und verschiedenen Medien zu veröffentlichen.</p>\n<p>Für alle Teilnehmer, die auf der Bühne stehen oder an der Vorlesung teilnehmen<a href=\"https://ja.confcodeofconduct.com/\" rel=\"nofollow\">Verhaltensregeln(Conference Code of Conduct)</a>Bitte folgen Sie den. Bitte beachten Sie, dass wir alle Maßnahmen ergreifen werden, einschließlich der Entlassung aus der Veranstaltung, wenn die Event-Management-Seite feststellt, dass es sich um eine schwerwiegende Belästigung handelt.</p>",
"event_url": "https://gaiax.connpass.com/event/173835/",
"started_at": "2020-05-07T19:30:00+09:00",
"ended_at": "2020-05-07T22:00:00+09:00",
"limit": null,
"hash_tag": "Flattern zum Anfassen",
"event_type": "participation",
"accepted": 106,
"waiting": 0,
"updated_at": "2020-05-07T21:44:47+09:00",
"owner_id": 11134,
"owner_nickname": "norinux",
"owner_display_name": "norinux",
"place": "online",
"address": "online",
"lat": null,
"lon": null,
"series": {
"id": 3109,
"title": "Gaiax Technical Meetups",
"url": "https://gaiax.connpass.com/"
}
}
]
}
Dieses Mal möchte ich es einfach ausprobieren, also werde ich eine Datenklasse in der Web-Benutzeroberfläche definieren. Gehen Sie zu https://app.quicktype.io/ und fügen Sie die zuvor vorbereiteten JSON-Daten in das Eingabefeld links ein.
Wenn Sie Python auswählen und "Nur Klassen" aktivieren, sollte das Konvertierungsergebnis automatisch auf der rechten Seite angezeigt werden. Aktivieren Sie außerdem "Eigenschaftsnamen in Pythonic umwandeln" für eine spätere Konvertierung mit Dacite.
Wenn Sie "Nur Klassen" deaktivieren, wird übrigens auch die Methode "to_dict ()" usw. definiert. Es ist jedoch erforderlich, jede Methode jedes Mal neu zu schreiben, wenn eine Spaltenänderung auftritt. Indem Sie Dacite diese Konvertierungen überlassen, können Sie die Codierungslast verringern.
Außerdem ist Quicktype gut gelungen und fügt Eigenschaften, die möglicherweise im Array enthalten sind oder nicht, "Optional" hinzu. Versuchen Sie, die Spalte "event_id" eines der beiden Ereignisse in JSON bei Quicktype zu entfernen.
Standardmäßig lautet der Klassenname der generierten Datenklasse "Willkommen". Ändern Sie ihn daher entsprechend. In diesem Artikel nennen wir es "Connpass".
Kopieren Sie abschließend die konvertierte Datenklasse vollständig und speichern Sie sie als Datei.
Speichern Sie es hier in connpass.py
entsprechend dem Klassennamen der Datenklasse.
Nachdem wir die Datenklasse definiert haben, verwenden wir Dacite, um von JSON in Datenklasse zu konvertieren.
Angenommen, der ursprüngliche JSON wird in einer Datei als "connpass.json" gespeichert, lautet der Code wie folgt.
main.py
import json
from dataclasses import dataclass
from datetime import datetime
from dacite import Config, from_dict
from connpass import Connpass
def run():
with open("connpass.json", "r") as f:
data = json.load(f)
connpass = from_dict(Connpass, data, Config({datetime: datetime.fromisoformat}))
print(connpass.events)
if __name__ == "__main__":
run()
Die eigentliche Konvertierung erfolgt in dieser Zeile.
connpass = from_dict(Connpass, data, Config({datetime: datetime.fromisoformat}))
Config
führt eine Typkonvertierung mit der Cast-Funktion von Dacite durch.
Ich übergebe datetime.fromisoformat
durch eine Eigenschaft, deren Typ datetime
ist.
Wenn Sie dies nicht schreiben, übergeben Sie "str" an die Eigenschaft "datetime" und "dacite.exceptions.WrongTypeError" wird ausgelöst.
connpass = from_dict(Connpass, data)
# dacite.exceptions.WrongTypeError: wrong value type for field "events.started_at" - should be "datetime" instead of value "2020-05-29T19:30:00+09:00" of type "str"
__post_init__ ()
Diesmal war die Besetzung übrigens ausreichend, aber wenn der Konvertierungsprozess je nach Eigenschaft unterschiedlich ist, obwohl es sich um denselben Typ handelt, können Sie ihn mit Union akzeptieren und manuell mit __post_init__ ()
konvertieren.
post_init_example.py
# {"text": "hello world", "created_at": "Thu Jun 04 11:27:06 +0900 2020", "timestamp": 1591237626}
from typing import Union
from datetime import datetime
@dataclass
class Sample:
text: str
created_at: Union[str, datetime]
timestamp: Union[int, datetime]
def __post_init__(self):
self.__convert_created_at()
self.__convert_timestamp()
def __convert_created_at(self):
if type(self.created_at) is str:
self.created_at =datetime.strptime(self.created_at, "%a %b %d %H:%M:%S %z %Y")
def __convert_timestamp(self):
if type(self.timestamp) is int:
self.timestamp = datetime.fromtimestamp(self.timestamp)
Das Aufrufen von "connpass = from_dict" (Connpass, data, Config ({datetime: datetime.fromisoformat})) ist jedes Mal schmerzhaft, daher verschieben wir den Konvertierungsprozess in die "Connpass" -Klasse.
connpass.py
from dataclasses import asdict, dataclass
from datetime import datetime
from typing import Any, Dict, List
from dacite import Config, from_dict
#Kürzung
@dataclass
class Connpass:
results_start: int
results_returned: int
results_available: int
events: List[Event]
@classmethod
def from_dict(cls, data: Dict[str, Any]) -> "Connpass":
return from_dict(cls, data, config=Config({datetime: datetime.fromisoformat}))
def to_dict(self) -> Dict[str, Any]:
return asdict(self)
Dann können Sie es so nennen. Es ist einfacher zu bedienen.
connpass = Connpass.from_dict(data)
exported_data = connpass.to_dict()
Bisher haben wir eine einfache Möglichkeit eingeführt, JSON- und Datenklassenkonvertierungen mithilfe von Dacite und Quicktype zu implementieren.
Das auf GitHub veröffentlichte Repository enthält auch ein Beispiel für das Einrichten eines einfachen Servers und das Überprüfen seines Betriebs. https://github.com/gaiax/quicktype-dacite-demo
Die Ergänzung wird auch funktionieren, sodass sich die Entwicklungserfahrung im Vergleich zum Spielen mit einem einfachen Wörterbuch erheblich verbessert hat. Ich bin glücklich.
Recommended Posts