Die Notation @ classmethod
, die in Python-Klassen erscheint. Organisieren Sie, was dies bedeutet, wie Sie es verwenden und was nützlich ist.
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
① 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.)
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
Variable zum Speichern der neu dekorierten Funktion=Dekorateur (zu dekorierende Funktion)
Variable zum Speichern der neu dekorierten Funktion()
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. ..
@Name des Dekorateurs
def Dekorierte Funktion()
Funktion
Dekorierte Funktion()
@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.
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)
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.
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.
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.
Was ist @classmethod, wie oben erwähnt?
Recommended Posts