[PYTHON] Sie können Assert- und Enum- (oder) Dekorateure verwenden, um die Einhaltung der Einschränkungen für Typanmerkungen ohne die Hilfe von mypy zu überprüfen.

0. Einleitung

Für die Python3-Typprüfung sind Typisierung und Mypy bekannt.


@ Mski_iksms Qiita-Artikel "Typprüfung von Python mit typehint und mypy"@ Papi_tokeis Qiita-Artikel "Übung !! Einführung in den Python-Typ (Typhinweise)"SWEet "Lassen Sie uns mit Python prüfen"Mizzsugars Blog "Der erste Schritt des generischen Lernens mit Python und TypeScript"


__ Dieser * mypy * prüft, ob die Einschränkung für Typanmerkungen von außerhalb der Python-Skriptdatei befolgt wird. __ __

Mit der Anweisung __ * assert * und dem Aufzählungstyp * Enum * können Sie den Typ und den Wert von Methodenargumenten überprüfen und Werte in einer geschlossenen (in sich geschlossenen) Form in der Skriptdatei zurückgeben. __ __

__ Dasselbe kann mit Dekoratoren implementiert werden. __ __

1. Verwendung von * assert * und * Enum *

(Referenz)

Note.nkmk.me "Typfunktion zum Abrufen / Bestimmen des Typs mit Python, isinstance-Funktion" ・ [CodeZine "Erklärung zur Verwendung der Funktion" Assertion ", die in Python wirklich nützlich ist! Aus "Python Trick"]](https://codezine.jp/article/detail/12179) ・ Was ist eine Assert-Aussage?

(Problemstellung)

  1. Verwenden Sie * spacy *, um bestimmte "proprietäre" Wörter aus einem Satz zu extrahieren. Wenn mehrere Wörter gefunden werden, die zu dem angegebenen "eindeutigen Ausdruck" gehören, wird gezählt, wie oft jedes Wort im Satz erscheint, und die Wörter werden in der Reihenfolge der Häufigkeit des Auftretens zurückgegeben.
  2. Es gibt eine Grenze für die Typen (Bezeichnungen) von "eindeutigen Ausdrücken", die * spacy * erkennen kann.
  3. Der Benutzer gibt als Argument an, welches Wort "eindeutiger Ausdruck" er aus dem Satz extrahieren möchte.
  4. Die Methode akzeptiert zwei Argumente. Der erste ist der zu analysierende Satz (muss vom Typ * str * sein) und der zweite ist die Bezeichnung (Name) des "eindeutigen Ausdrucks".
  5. Wenn die als Argument übergebenen Textdaten nicht vom Typ * str * sind, wird ein Fehler zurückgegeben. Wenn der als Argument übergebene Labelname "eindeutiger Ausdruck" nicht im definierten Label "eindeutiger Ausdruck" gefunden wird, wird ein Fehler zurückgegeben.

Python3


from enum import Enum
from typing import List, Dict
import spacy

class NamedEntityLabel(Enum):
	Jinmei : str = "PERSON"
	Chimei : str = "LOC"

	def extract_named_entity_wordlist(text : str, ne_label : str) -> List[str]:
		#Überprüfen Sie den Typ des ersten Arguments
		assert type(text) is str, 'Die eingegebenen Textdaten müssen eine Zeichenfolge sein.'
		#Überprüfen Sie den Wert des zweiten Arguments
		right_value_list = [e.name for e in NamedEntityLabel]
		assert ne_label in right_value_list, 'Die eingegebene eindeutige Ausdrucksbezeichnung wurde noch nicht definiert.'
		#Wenn es kein Problem mit dem Typ und dem Wert der beiden empfangenen Argumente gibt, führen Sie Folgendes aus
    	nlp = spacy.load('ja_ginza')
   	 	text = text.replace("\n", "")
    	doc = nlp(text)
    	word_list = [ent.text for ent in doc.ents if ent.label_ == NamedEntityLabel[ne_label].value]
    	return word_list
    	

Politik

Sie können __ * schreiben, wenn ne_label nicht in ["PERSON", "LOC"] , sondern hier, um den "vordefinierten eindeutigen Ausdruckstyp" im Code explizit zu beschreiben, die "eindeutige Ausdrucksklasse" Wird durch den Aufzählungstyp ( Enum *) definiert. __ __

Versuchen Sie es mit

(Wenn der beabsichtigte Wert als Argument übergeben wird)

__ Extrahieren Sie die Wörter, die der angegebenen eindeutigen Ausdrucksbezeichnung entsprechen, aus dem empfangenen * Text * -Satz und geben Sie jedes Wort in der Reihenfolge der Häufigkeit des Auftretens zurück. (Extraktion eindeutiger Ausdrücke: * Erkennung benannter Entitäten *) __

Python3


text = """Heute bin ich mit Mary nach Amerika gekommen. Ich ging durch Paris, Frankreich."""
 
NamedEntityLabel.extract_named_entity_wordlist(text, "Chimei")
#Ergebnis
['Amerika', 'Frankreich', 'Paris']

NamedEntityLabel.extract_named_entity_wordlist(text, "Jinmei")
#Ergebnis
['Maria']

(Wenn ein unbeabsichtigter Wert als Argument übergeben wird)

Python3


NamedEntityLabel.extract_named_entity_wordlist(text, "Soshikimei")
#Ergebnis
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 7, in extract_named_entity_wordlist
AssertionError:Die eingegebene eindeutige Ausdrucksbezeichnung ist noch nicht definiert

Python3


NamedEntityLabel.extract_named_entity_wordlist(127, "Soshikimei")
#Ergebnis
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 5, in extract_named_entity_wordlist
AssertionError:Die eingegebenen Textdaten müssen eine Zeichenfolge sein.

Python3


NamedEntityLabel.extract_named_entity_wordlist(127, "Jinmei")
#Ergebnis
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 5, in extract_named_entity_wordlist
AssertionError:Die eingegebenen Textdaten müssen eine Zeichenfolge sein.

Sie können auch Dekorateure wie die folgende Webseite verwenden.

Als nächstes wollen wir sehen, wie man den Dekorator benutzt.

2. Verwendung von Decorator und * Enum * ohne Verwendung von * assert *

Python3


class NamedEntityLabel(Enum):
	Jinmei : str = "Person"
	Chimei : str = "LOC"
	Soshikimei :str = "ORG"
    @classmethod
    def value_check(cls, target_value):
        for e in NamedEntityLabel:
            if e.name == target_value:
                return e
        raise ValueError('{}Ist keine definierte eindeutige Ausdrucksbezeichnung'.format(target_value))

(Wie benutzt man)

Python3


NamedEntityLabel.value_check("Jinmei")

#Ausführungsergebnis
NamedEntityLabel.value_check("Jinmei")
<NamedEntityLabel.Jinmei: 'Person'>

Python3


NamedEntityLabel.value_check("EmailAddress")

#Ausführungsergebnis
ValueError:EmailAddress ist keine definierte eindeutige Ausdrucksbezeichnung

Erstellen Sie den folgenden Code mit den oben genannten

Python3


class NamedEntityLabel_2(Enum):
	Jinmei : str = "PERSON"
	Chimei : str = "LOC"
    @classmethod
    def value_check(cls, target_value):
        for e in NamedEntityLabel_2:
            if e.name == target_value:
                return e
        raise ValueError('{}Ist keine definierte eindeutige Ausdrucksbezeichnung
'.format(target_value))
        
	def extract_named_entity_wordlist(text : str, ne_label : str) -> List[str]:
		#Überprüfen Sie den Typ des ersten Arguments
		assert type(text) is str, 'Die eingegebenen Textdaten müssen eine Zeichenfolge sein.'
		#Überprüfen Sie den Wert des zweiten Arguments
		e = NamedEntityLabel_2.value_check(ne_label)
		#Wenn es kein Problem mit dem Typ und dem Wert der beiden empfangenen Argumente gibt, führen Sie Folgendes aus
    	nlp = spacy.load('ja_ginza')
   	 	text = text.replace("\n", "")
    	doc = nlp(text)
    	word_list = [ent.text for ent in doc.ents if ent.label_ == e.value]
    	return word_list

(Wenn der beabsichtigte Wert als Argument übergeben wird)

Python3


text = """Heute bin ich mit Mary nach Amerika gekommen. Ich ging durch Paris, Frankreich."""
 
NamedEntityLabel_2.extract_named_entity_wordlist(text, "Chimei")
#Ergebnis
['Amerika', 'Frankreich', 'Paris']

(Wenn ein unbeabsichtigter Wert als Argument übergeben wird)

Python3


NamedEntityLabel_2.extract_named_entity_wordlist(text, "Soshikimei")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 12, in extract_named_entity_wordlist
  File "<stdin>", line 9, in value_check
ValueError:Soshikimei ist keine definierte eindeutige Ausdrucksbezeichnung

Python3


NamedEntityLabel_2.extract_named_entity_wordlist(127, "Soshikimei")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 11, in extract_named_entity_wordlist
AssertionError:Die eingegebenen Textdaten müssen eine Zeichenfolge sein.

(Referenz)

Der Code, mit dem mithilfe eines Dekorators überprüft wird, ob die Typanmerkungsbeschränkung der Methode eingehalten wird, wird auch auf der folgenden Webseite vorgeschlagen.

CosmoSonic21-Blog "Funktionsargumenttypprüfung mit Decorator in Python implementieren"


3. Verwendung der Klasseninstanz * Enum *, die durch Übergeben des empfangenen Arguments an den Konstruktor bei der Verarbeitung des Hauptteils erstellt wurde

Das Folgende ist das einfachste.

( Methode )

  1. Übergeben Sie den empfangenen eindeutigen Ausdrucksbezeichnungsnamen an den Instanzkonstruktor der Aufzählungsklasse (in der der eindeutige Ausdruck definiert ist), um eine Instanz der eindeutigen Ausdrucksklasse zu erstellen.
  2. Die Datenverarbeitung verwendet die generierte Instanz der eindeutigen Ausdrucksklasse.
  3. Wenn eine undefinierte eindeutige Ausdrucksbezeichnung empfangen wird, tritt beim Erstellen einer Instanz der eindeutigen Ausdrucksklasse ein Schlüsselfehler auf, und es wird keine weitere Verarbeitung durchgeführt.

__ Übergeben Sie zunächst einen geeigneten eindeutigen Ausdrucksbezeichnungsnamen an den Konstruktor und überprüfen Sie, was passiert, wenn Sie versuchen, eine Instanz der Aufzählungstypklasse zu erstellen (in der der eindeutige Ausdruck definiert ist). __ __

__ Klassendeklaration vom Aufzählungstyp (* Enum *) __

Python3


from enum import Enum
import enum
from typing import List, Dict

@enum.unique
class NamedEntityLabel(Enum):
Jinmei : str = "PERSON"
Chimei : str = "LOC"

__ Übergeben Sie beliebige Daten an den Konstruktor, um eine Instanz der Klasse Enumerationstyp (* Enum *) zu erstellen. __

__ (Wenn der übergebene Wert * Name * ist, der in der Klasse * Enum * definiert ist) __ __ Instanz wurde erfolgreich erstellt __

Python3


named_entity_instance_test = NamedEntityLabel["Jinmei"]
print(named_entity_instance_test)
#Ausführungsergebnis: Die Instanz wurde erfolgreich erstellt
NamedEntityLabel.Jinmei
#Extrahieren Sie den Namen der generierten Instanz
print(named_entity_instance_test.name)
#Ausführungsergebnis
Jinmei
#Extrahieren Sie den Wert der generierten Instanz
print(named_entity_instance_test.value)
#Ausführungsergebnis
PERSON

__ (Wenn der übergebene Wert * Name * in der Klasse * Enum * undefiniert ist) __ __ Es wird keine Instanz erstellt und ich erhalte eine Fehlermeldung __

Python3


named_entity_instance_test = NamedEntityLabel["EMAIL"]
#Ausführungsergebnis: Ein Fehler ist aufgetreten, weil in der NamedEntityLabel-Klasse ein undefinierter Name übergeben wurde (Aufzählungstyp Aufzählungstyp).
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/ocean/.pyenv/versions/3.9.0/lib/python3.9/enum.py", line 355, in __getitem__
    return cls._member_map_[name]
KeyError: 'EMAIL'

__ (Wenn der übergebene Wert * Name * ist, der in der Klasse * Enum * definiert ist) __ __ Instanz wurde erfolgreich erstellt __

Python3


#Variablen, die beim Erstellen einer Instanz der NamedEntityLabel-Klasse an den Konstruktor übergeben werden
#Diese Variable geht davon aus, dass der vom Benutzer empfangene Wert gespeichert wird
input_data_ok = "Jinmei"
input_data_ng = "Emailaddress"

named_entity_instance_ok = NamedEntityLabel[input_data_ok]
#Kein Fehler
print(named_entity_instance_ok)
#Ausführungsergebnis: Die Instanz wurde erfolgreich erstellt
NamedEntityLabel.Jinmei
#Extrahieren Sie den Namen der generierten Instanz
print(named_entity_instance_ok.name)
#Ausführungsergebnis
Jinmei
 
#Extrahieren Sie den Wert der generierten Instanz
print(named_entity_instance_ok.value)
#Ausführungsergebnis
PERSON

__ (Wenn der übergebene Wert * Name * in der Klasse * Enum * undefiniert ist) __ __ Es wird keine Instanz erstellt und ich erhalte eine Fehlermeldung __

Python3


named_entity_instance_ng = NamedEntityLabel[input_data_ng]
#Ausführungsergebnis: Ein Fehler ist aufgetreten, weil in der NamedEntityLabel-Klasse ein undefinierter Name übergeben wurde (Aufzählungstyp Aufzählungstyp).
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/ocean/.pyenv/versions/3.9.0/lib/python3.9/enum.py", line 355, in __getitem__
    return cls._member_map_[name]
KeyError: 'Emailaddress'

Schreiben Sie nach Erhalt des oben genannten Skripts das gesamte Skript __ neu

@ Ksato9700s Qiita-Artikel "Was ist neu in Python 3.4.0 (2) --enum"

(1) Definieren Sie die Klasse * Enum *

__ Definieren Sie die verfügbaren eindeutigen Ausdrucksbezeichnungsnamen als Aufzählungsklasse __

Python3


class NamedEntityLabel_3(Enum):
    Jinmei : str = "PERSON"
    Chimei : str = "LOC"

(2) Definieren Sie eine Methode zur Verarbeitung des Hauptkörpers

__ Beachten Sie die folgenden zwei Zeilen __

__ (Platz 1) __ named_entity_instance = NamedEntityLabel_3[ne_label]

__ (2. Platz) __ word_list = [ent.text for ent in doc.ents if ent.label_ == named_entity_instance.value]

Python3


def extract_named_entity_wordlist(text : str, ne_label : str) -> List[str]:
	#Überprüfen Sie den Typ des ersten Arguments
    assert type(text) is str, 'Die eingegebenen Textdaten müssen eine Zeichenfolge sein.'
    #Überprüfen Sie den Wert des zweiten Arguments
    #Wenn das als Argument empfangene Wort ein undefiniertes Wort als Name der NamedEntityLabel-Klasse ist, tritt ein Schlüsselfehler auf, wenn Sie versuchen, dieses Wort an den Konstruktor zu übergeben, um eine Anweisung für NamedEntityLabel zu generieren.
    named_entity_instance = NamedEntityLabel_3[ne_label]
    #Wenn es kein Problem mit dem Typ und dem Wert der beiden empfangenen Argumente gibt, führen Sie Folgendes aus
    nlp = spacy.load('ja_ginza')
    text = text.replace("\n", "")
    doc = nlp(text)
    word_list = [ent.text for ent in doc.ents if ent.label_ == named_entity_instance.value]
    return word_list

(Wenn der beabsichtigte Wert als Argument übergeben wird)

Python3


extract_named_entity_wordlist(text, "Chimei")
#Ausführungsergebnis
['Amerika', 'Frankreich', 'Paris']

(Wenn ein unbeabsichtigter Wert als Argument übergeben wird)

Python3


extract_named_entity_wordlist(text, "Soshikimei")
#Ausführungsergebnis
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 6, in extract_named_entity_wordlist
  File "/Users/ocean/.pyenv/versions/3.9.0/lib/python3.9/enum.py", line 355, in __getitem__
    return cls._member_map_[name]
KeyError: 'Soshikimei'

Recommended Posts

Sie können Assert- und Enum- (oder) Dekorateure verwenden, um die Einhaltung der Einschränkungen für Typanmerkungen ohne die Hilfe von mypy zu überprüfen.
Sie können auch die Kommunikation von DB und Cache mit Curl überprüfen
Technisches Englisch> Sie verwenden die booleschen Operatoren [und, oder und nicht], um ...> Boolesche Operationen - und oder oder nicht
Verwenden Sie die Bash-Vervollständigung, um lange Befehle einzugeben, ohne den Menschen oder die Hilfe anzusehen
Überprüfen Sie den Typ der von Ihnen verwendeten Variablen
Ich habe versucht, mit Hilfe des neuronalen Netzes zu überprüfen, ob "Japanisch" nur "unlesbare Schriftarten" wirklich nur von Japanisch gelesen werden können
Site-Hinweise zur Verwendung von NetworkX mit Python
Überprüfen Sie den Linux-Verteilungstyp und die Version