[Python] Was sind @classmethod und Dekorateure?

Was in diesem Artikel zu schreiben

Die Notation @ classmethod, die in Python-Klassen erscheint. Organisieren Sie, was dies bedeutet, wie Sie es verwenden und was nützlich ist.

Was ist @classmethod?

Was ist ein Dekorateur?

Um Dekoratorausdrücke zu verstehen, müssen Sie sich mit Dekoratoren auskennen. Ein Dekorator ist eine Funktion **, die eine Funktion empfängt und eine neue Funktion zurückgibt.

Es kann mit den folgenden Eigenschaften der Funktion erstellt werden. ① Funktionen sind Variablen zugeordnet ② Andere Funktionen können in der Funktion definiert werden ③ Die Funktion kann die Funktion zurückgeben ④ Sie können eine Funktion an das Argument einer bestimmten Funktion übergeben

Ich werde versuchen zu sehen, ob die oben genannten true ~ ④. Sind wahr ↓

① Funktionen sind Variablen zugeordnet



#Funktionsdefinition
def big(word="hello world"):
    return word.capitalize()+"!"
print(big()) # <- Hello world!

#Da Funktionen Objekte sind, können sie Variablen zugewiesen und verwendet werden.
big2 = big
print(big2()) # Hello world!

② Andere Funktionen können in der Funktion definiert werden


#Funktionsverschachtelung
def tension():
    x = 'by neko like man'
    # low()tenstion()Definiert in
    def low(word='Hello World'):
        return word + '...' + x
    #Sofort ausführen
    print(low())
    
# low()Ist Spannung()Wird bei jedem Anruf definiert
tension() # <- Hello World...by neko like man

#Aber niedrig()Ist Spannung()Von außen nicht zugänglich
try:
    print(low())
except NameError:
    print('No low') # <- No low

Die "niedrige Funktion" wird innerhalb der "Spannungsfunktion" definiert. Auch die in der "Spannungsfunktion" definierte "Variable x" kann in der internen Funktion "niedrig" verwendet werden. Zu diesem Zeitpunkt wird die "niedrige Funktion" als Verschluss und die "Spannungsfunktion" als Gehäuse bezeichnet. Außerdem sind Variablen, die in einem Codeblock verwendet werden, aber in diesem Codeblock nicht definiert sind, wie z. B. "Variable x", freie Variablen (freie Variable. Es heißt 3 / reference / executemodel.html # naming-and-binding)). (Es ist grundsätzlich nicht möglich, den Wert von "Variable x" aus einer internen Funktion heraus zu ändern (es ist möglich, "nicht lokal" zu verwenden))

③ Die Funktion kann die Funktion zurückgeben


def dragonball():
    #Freie Variablen x und y
    x = 100
    y = 100
    # fusiton()Dann die äußere Funktion(dragonball())X definiert in,Y halten
    # fusion()Ist eine Schließung, dragonball()Ist das Gehäuse
    def fusion(left='goku', light='trunks'):
        #Nicht lokal, wenn Sie den Wert einer freien Variablen innerhalb des Abschlusses aktualisieren möchten()verwenden
        nonlocal x
        x = 900
        return f'{left}"Fu..." Stärke:{x} \
        {light}"Fu...." Stärke:{y} \
        {left}, {light}"John !!" Stärke:{x+y}'
    #Definiert und in der Dragonball-Funktion zurückgegeben.()Gibt ein Funktionsobjekt ohne zurück.
    return fusion

x = dragonball()
print(x())
#↑ goku "Fu"..." Stärke:900 Stämme "Fu"...." Stärke:100  goku, trunks「ジョン!!" Stärke:1000
print(x('piccolo','kuririn'))
#↑ piccolo "Fu..." Stärke:900 kuririn "Fu...." Stärke:100  piccolo, kuririn「ジョン!!" Stärke:1000

Die function dragonball () gibt die intern definierte function fusion zurück. Durch die Rückgabe eines Funktionsobjekts ohne () hat die Variable x den Rückgabewert von dragonball () übergeben und kann fusion () verwenden.

④ Sie können eine Funktion an das Argument einer bestimmten Funktion übergeben


def hand_over(func):
    print('hand over')
    print(func())
    
hand_over(dragonball())
# ↑ hand over
#Goku "Fu"..." Stärke:900 Stämme "Fu"...." Stärke:100         goku, trunks「ジョン!!" Stärke:1000

Sie können die Funktion Dragonball als Argument an die Funktion Hand_over übergeben. Der "Funktionsdrachenball" enthält die "interne Funktionsfusion", und die "Funktionsübergabe" wird an die "interne Funktionsfusion" übergeben. Beachten Sie, dass die Funktion, die übergeben werden kann (in diesem Fall "hand_over ()"), nicht von selbst funktioniert, da möglicherweise andere Funktionen vorhanden sind.


Wie oben erwähnt, die Funktion ① Funktionen sind Variablen zugeordnet ② Andere Funktionen können in der Funktion definiert werden ③ Die Funktion kann die Funktion zurückgeben ④ Sie können eine Funktion an das Argument einer bestimmten Funktion übergeben Es hat vier Eigenschaften wie.

Der Dekorator ist eine Funktion, die unter Verwendung der Eigenschaften von (2), (3) und (4) oben definiert wurde und unter Verwendung der Eigenschaften von (1) verwendet wird.

Mit anderen Worten, was ist ein Dekorateur? ** Eine Funktion, die Funktion A empfängt, Funktionen hinzufügt und eine neue Funktion A_ver2.0 zurückgibt. Die Funktion A_ver2.0 wird verwendet, indem sie einer Variablen zugewiesen wird. ** ** **

Bei der Herstellung eines Dekorateurs

Infolgedessen wird die Funktion A_ver2.0 mit hinzugefügten Funktionen geboren und kann in Form von "X ()" verwendet werden. (Ich dachte, es wäre ähnlich wie Mixin in der Klasse.)

Versuchen Sie es mit einem Dekorateur

Wie man einen Dekorateur macht

def Dekorateur Name(Wo soll die dekorierte Funktion platziert werden?):
    #Erstellen Sie Argumente mit variabler Länge, damit jedes Argument der zu dekorierenden Funktion verarbeitet werden kann
def Dekorateur(*args, **kwargs): 
        #Rufen Sie die zu dekorierende Funktion auf (Sie können die ursprüngliche Funktion unverändert verwenden oder bearbeiten).
        result = func(*args, **kwargs)
        #Funktionen, die Sie durch Dekorieren hinzufügen möchten
Rückkehr Dekorateur# <-Enthält dekorierte Elemente

def Dekorierte Funktion()
Funktion

So verwenden Sie den decorator_1

Variable zum Speichern der neu dekorierten Funktion=Dekorateur (zu dekorierende Funktion)
Variable zum Speichern der neu dekorierten Funktion()

Trainieren

Angenommen, Sie haben eine Funktion, die auflistet und anzeigt, was Sie kaufen möchten.

Funktion bekommen_fruits


def get_fruits(*args):
    basket = []
    for i in args:
        basket.append(i)
    print(basket)
    

get_fruits('apple','banana') # <- ['apple', 'banana']

Ich werde dies mit den Tweets in meinem Herzen dekorieren.

Funktion bekommen_fruits_ver2.0


#Dekorateur
def deco(func): #④
    def count(*args): #②
        print('Was zu kaufen')
        func(*args)
        print('Okay, lass uns das machen')
    return count #③

def get_fruits(*args):
    basket = []
    for i in args:
        basket.append(i)
    print(basket)

# get_fruits()Deko()Mit dekorieren
#Übergeben Sie das Dekorationsargument mit der Funktion, die Sie dekorieren möchten, an die Variable
#Wenn Sie dieser Variablen ein Argument übergeben und es ausführen, deco+ get_Früchte funktionieren (bekommen_fruits_ver2.0) wird ausgeführt
deco_get_fruits = deco(get_fruits) #①
deco_get_fruits('apple','banana')
#↑ Was zu kaufen
#   ['apple', 'banana']
#Okay, lass uns das machen

Indem Sie das Objekt der mit dem Dekorator erstellten Funktion in die Variable (deco_get_fruits) einfügen, kann die funktions hinzugefügte Version von get_fruits verwendet werden. Durch Speichern des Objekts der mit dem Dekorator erstellten Funktion im Variablennamen mit demselben Namen wie die dekorierte Funktion kann es auch von der dekorierten Funktion überschrieben werden.


get_fruits = deco(get_fruits)
get_fruits('apple','banana')
#↑ Was zu kaufen
#   ['apple', 'banana']
#Okay, lass uns das machen

Wie oben erwähnt, wird die Funktion ver2.0 durch Zuweisen des Rückgabewerts des Dekorators zur Variablen erstellt. Wenn Sie jedoch den Dekoratorausdruck verwenden, müssen Sie ihn nicht einzeln der Variablen zuweisen, und der Code ist sauber. ..

Verwendung von decorator_2: Verwenden Sie die Decorator-Formel

@Name des Dekorateurs
def Dekorierte Funktion()
Funktion

Dekorierte Funktion()

Trainieren

@deco
def get_vegetable(*args):
    basket = []
    for i in args:
        basket.append(i)
    print(basket)
    
get_vegetable('tomato','carrot')
#↑ Was zu kaufen
#   ['tomato', 'carrot']
#Okay, lass uns das machen

Durch Schreiben von "@decorator name" in die vorherige Zeile der Funktionsdefinition wird die direkt darunter definierte Funktion dekoriert und dem Variablennamen mit demselben Namen wie diese Funktion zugewiesen. Mit anderen Worten, der Inhalt der Variablen wird durch die Funktion ver_2.0 überschrieben. Synonym für den folgenden Code.

#Eine Variable mit demselben Namen wie der Name der dekorierten Funktion=Dekorateur (zu dekorierende Funktion)
get_vegitable = deco(get_vegetable)

Usage_2 ist leichter zu erkennen als Usage_1. Auf diese Weise ist der Verarbeitungsinhalt derselbe, aber die Syntax ist einfach und leicht zu lesen. Sie heißt ** Syntax Sugar **.

Wie oben erwähnt, können Sie bei Verwendung des Decorator-Ausdrucks die Zuordnung zur Variablen weglassen, und es scheint, dass die Lesbarkeit verbessert ist. Das Hauptthema dieses Artikels, "@ classmethod", ist auch ein Dekorationsausdruck. Wir rufen die eingebaute Funktion classmethod () auf. classmethod () hat eine Funktion zum Konvertieren der in der Klasse definierten Methode in eine Klassenmethode.

classmethod Klassenmethode ist eine Methode, die verwendet werden kann, ohne eine Instanz der Klasse zu erstellen. Es scheint verwendet zu werden, wenn Sie eine Instanz nach der Verarbeitung innerhalb der Klasse im Voraus erstellen möchten.

Konkretes Beispiel

Beispielsweise wird im Detetime-Modul die Today-Methode der Datumsklasse als Klassenmethode definiert, die die von der Epoche (1. Januar 1970, 00:00:00) verstrichene Zeit in die Ortszeit umwandelt und die erforderlichen Informationen benötigt ( Jahr, Monat, Tag) ist zurückzugeben.

datetime Modul heute Methode der Datumsklasse


class date:
 #Abkürzung
    @classmethod
    def fromtimestamp(cls, t):
        "Construct a date from a POSIX timestamp (like time.time())."
        y, m, d, hh, mm, ss, weekday, jday, dst = _time.localtime(t)
        return cls(y, m, d)

    @classmethod
    def today(cls):
        "Construct a date from time.time()."
        t = _time.time()
        return cls.fromtimestamp(t)
Persönliche Studie namens Kommentar

Um den obigen Code zu verstehen, werde ich ihn in Sätzen neu organisieren.

Die heutige Klassenmethode verwendet die "Zeitfunktion" der "eingebauten Modulzeit", die als "Zeit" bezeichnet wird, um die verstrichene Zeit aus der Epoche (beim Schreiben dieses Blogs den Wert 1576760183.8697512 zurückgegeben) der Variablen t zuzuweisen. .. Wir übergeben es als Argument an die "fromtimestamp class method".

Bei der Methode "fromtimestamp class" wird die Variable t in die Funktion "localtime ()" des Zeitmoduls eingefügt. Wenn Sie localtime () verwenden, werden die Zahlen in der Variablen t in Monate, Tage, Sekunden usw. sortiert und im Taple gespeichert, sodass sie leicht zu verstehen und bequem sind. (Wenn Sie "localtime ()" ohne Argument verwenden, wird die Ortszeit angezeigt.)

time.struct_time(tm_year=2019, tm_mon=12, tm_mday=19, tm_hour=12, tm_min=56, tm_sec=41, tm_wday=3, tm_yday=353, tm_isdst=0)

Jedes von diesen wird in den Variablen "y, m, d, hh, mm, ss, Wochentag, jTag, dst" gespeichert, und schließlich wird nur "y", "m", "d" zurückgegeben.

Daher können Sie das aktuelle Jahr y Monat m Tag d erhalten, indem Sie die Today-Klassenmethode ausführen.

Was ist nützlich?

Ich bin noch unerfahren, aber ich habe die Vorzüge der Klassenmethode nicht verstanden, sondern persönlich: "Ich möchte die Klasse initialisieren, aber der Code wird kompliziert. Initialisieren Sie ihn also an einer anderen Stelle als" init ". Ich habe es so arrangiert, dass es verwendet wird, wenn ich möchte. Betrachtet man das praktische Beispiel, so scheint es, dass der Prozess der Informationsbeschaffung von außen in der Klassenmethode definiert ist.

Ich habe mit @classmethod gespielt.

Als ich über den Code nachdachte, um Informationen von außen zu erhalten, schrieb ich [Blog](http://atc.hateblo.jp/entry/2018/06/26/%E6%AF%8E%E6%9C] % 9D% E8% 87% AA% E5% 8B% 95% E3% 81% A7% E9% 99% 8D% E6% B0% B4% E7% A2% BA% E7% 8E% 87% E3% 82% 92 % E6% 95% 99% E3% 81% 88% E3% 81% A6% E3% 81% 8F% E3% 82% 8C% E3% 82% 8B% E3% 83% 97% E3% 83% AD% E3 % 82% B0% E3% 83% A9% E3% 83% A0% E3% 82% 92% E4% BD% 9C), also habe ich den Code geschrieben, um die lokalen Wettervorhersageinformationen zu erhalten, also werde ich erneut Ich habe es versucht.

Ein Spiel, um die lokale Wettervorhersage zu erraten


import requests, xml.etree.ElementTree as ET, os

#Spiel, um die heutige Niederschlagswahrscheinlichkeit zu erraten
class Game(object):
  ch = []
  
  def __init__(self, am1, am2, pm1, pm2):
    self.am1 = am1
    self.am2 = am2
    self.pm1 = pm1
    self.pm2 = pm2
  
  @classmethod
  #Holen Sie sich die Wahrscheinlichkeit von Niederschlägen alle 6 Stunden aus dem Internet Southern Ibaraki
  def rain_percent(cls):
    r = requests.get('https://www.drk7.jp/weather/xml/08.xml')
    r.encoding = r.apparent_encoding
    root = ET.fromstring(r.text)
    area = root.findall(".//area[@id]")  #Norden und Süden
    south = area[1] #Knoten im südlichen Bereich
    info = south.findall('.//info[@date]') #7 Tage im Süden
    today = info[0] #Südlicher heutiger Minutenknoten
    period = today.findall('.//period[@hour]') 
    cls.ch = []
    for percent in period:
      cls.ch.append(percent.text)
    return cls.ch

  def quiz(self):
    print(f'Deine Antwort-> [{self.am1}-{self.am2}-{self.pm1}-{self.pm2}] :Die heutige Niederschlagswahrscheinlichkeit-> {Game.ch}')


play1 = Game(10,10,10,10)
play1.rain_percent()
play1.quiz() #Deine Antwort-> [10-10-10-10] :Die heutige Niederschlagswahrscheinlichkeit-> ['0', '10', '40', '50']

Es ist sowohl von der Klasse als auch von der Instanz ↓ zugänglich

Game.rain_percent()  # ['0', '10', '40', '50']
play1.rain_percent() # ['0', '10', '40', '50']

Es wird empfohlen, dass das erste Argument der Klassenmethode "cls" ist. Wenn Cls als "class name.class method ()" oder "instance name.class method ()" aufgerufen wird, hat cls "class name" oder Die "instanziierte Klasse" wird übergeben.

Zusammenfassung

Was ist @classmethod, wie oben erwähnt?

Recommended Posts

[Python] Was sind @classmethod und Dekorateure?
Was vergleichst du mit Python und ==?
Was sind Python Taples und * Args?
[Python] Python und Sicherheit - is Was ist Python?
Python a + = b und a = a + b sind unterschiedlich
(Anfänger) Was sind Kerne und Threads?
Module und Pakete in Python sind "Namespaces"
Was sind Go Mod, Go Get und Go Mod Anbieter?
Was sind Linux POSIX Option und GNU Option?
Python open und io.open sind gleich
Über Python Decorator
Was ist Python?
Über Python-Dekorateure
Was ist Python?
Trainingsdaten und Testdaten (Was sind X_train und y_train?) ①
Trainingsdaten und Testdaten (Was sind X_train und y_train?) ②
Was ist "funktionale Programmierung" und "objektorientiert"? Python Edition
[Python] Vor dem Unterstrich (Unterstrich) Was sind die beiden Funktionen?
[Mathematik] Visualisieren wir, was Eigenwerte und Eigenvektoren sind
Wie Python-Klassen und magische Methoden funktionieren.
Was verwenden Sie beim Testen mit Python?
Was ich denke, Python und Ruby (und Sprachen, deren Typen nicht angegeben sind) sind Mist
[Python] Komprimieren und dekomprimieren
Python- und Numpy-Tipps
[Python] Pip und Wheel
[Python] Was ist Pipeline ...
Funktionen und Dekorateure höherer Ordnung
Python Iterator und Generator
Python-Pakete und -Module
Vue-Cli- und Python-Integration
Python-Klassen sind langsam
Ruby, Python und Map
Python-Eingabe und Ausgabe
Python und Ruby teilen sich
Das von Python berechnete VIF und das von Excel berechnete VIF sind unterschiedlich.
Python asyncio und ContextVar
[Python] Was ist virtualenv?
Was ich über KI / maschinelles Lernen mit Python gelernt habe (4)
Unter CentOS (RHEL) 8 können keine Python- und Pip-Befehle verwendet werden
Einführung in die Effektüberprüfung Schreiben der Kapitel 4 und 5 in Python
[Python3] "A // B" und "math.floor (A / B)" sind nicht immer gleich! ??
Programmieren mit Python und Tkinter
Ver- und Entschlüsselung mit Python
Python: Klassen- und Instanzvariablen
3-3, Python-Zeichenfolge und Zeichencode
Python 2-Serie und 3-Serie (Anaconda Edition)
Python und Hardware-Verwenden von RS232C mit Python-
Python auf Ruby und wütend Ruby auf Python
Python-Einzug und String-Format
Python Real Number Division (/) und Integer Division (//)
Installieren Sie Python und Flask (Windows 10)
Informationen zu Python-Objekten und -Klassen
Informationen zu Python-Variablen und -Objekten
Apache mod_auth_tkt und Python AuthTkt
Was sind Umgebungsvariablen? (Linux)
[Python] if __name__ == Was ist '__ main__' :?
Lernen Sie Python-Pakete und -Module kennen