La notation «@ classmethod» qui apparaît dans les classes Python. Organisez ce que cela signifie, comment l'utiliser et ce qui est utile.
Pour comprendre les expressions des décorateurs, vous devez connaître les décorateurs. Un décorateur est une fonction ** qui reçoit une fonction et renvoie une nouvelle fonction.
Il peut être créé à l'aide des propriétés suivantes de la fonction. ① Les fonctions sont affectées aux variables ② D'autres fonctions peuvent être définies dans la fonction ③ La fonction peut renvoyer la fonction ④ Vous pouvez passer une fonction à l'argument d'une certaine fonction
① Les fonctions sont affectées aux variables
#Définition des fonctions
def big(word="hello world"):
return word.capitalize()+"!"
print(big()) # <- Hello world!
#Les fonctions étant des objets, elles peuvent être affectées à des variables et utilisées.
big2 = big
print(big2()) # Hello world!
② D'autres fonctions peuvent être définies dans la fonction
#Imbrication des fonctions
def tension():
x = 'by neko like man'
# low()tenstion()Défini dans
def low(word='Hello World'):
return word + '...' + x
#Exécutez immédiatement
print(low())
# low()Est la tension()Défini chaque fois que vous appelez
tension() # <- Hello World...by neko like man
#Mais bas()Est la tension()Non accessible de l'extérieur
try:
print(low())
except NameError:
print('No low') # <- No low
La «fonction basse» est définie à l'intérieur de la «fonction de tension».
De plus, la "variable x" définie dans la "fonction de tension" peut être utilisée dans la fonction interne "faible".
A ce moment, la «fonction basse» est appelée une fermeture et la «fonction de tension» est appelée une enceinte.
De plus, les variables qui sont utilisées dans un bloc de code mais qui ne sont pas définies dans ce bloc de code, telles que «variable x», sont des variables libres (variable libre. Il s'appelle 3 / reference / executionmodel.html # naming-and-binding)).
(Il n'est fondamentalement pas possible de changer la valeur de variable x
à partir d'une fonction interne (c'est possible en utilisant nonlocal
))
③ La fonction peut renvoyer la fonction
def dragonball():
#Variables libres x et y
x = 100
y = 100
# fusiton()Puis la fonction extérieure(dragonball())X défini dans,Tenant y
# fusion()Est une fermeture, dragonball()Est l'enceinte
def fusion(left='goku', light='trunks'):
#Non local si vous souhaitez mettre à jour la valeur d'une variable libre depuis la fermeture()utilisation
nonlocal x
x = 900
return f'{left}"Fu..." force:{x} \
{light}"Fu...." force:{y} \
{left}, {light}"John !!" Force:{x+y}'
#Défini et renvoyé dans la fonction Dragonball.()Renvoie un objet fonction sans.
return fusion
x = dragonball()
print(x())
#↑ goku "Fu"..." force:900 malles "Fu"...." force:100 goku, trunks「ジョン!!" force:1000
print(x('piccolo','kuririn'))
#↑ piccolo "Fu..." force:900 kuririn "Fu...." force:100 piccolo, kuririn「ジョン!!" force:1000
La function dragonball ()
renvoie la fonction fusion
définie en interne.
En retournant un objet fonction sans (), la variable x
a passé la valeur de retour de dragonball ()
peut utiliserfusion ()
.
④ Vous pouvez passer une fonction à l'argument d'une certaine fonction
def hand_over(func):
print('hand over')
print(func())
hand_over(dragonball())
# ↑ hand over
#goku "Fu"..." force:900 malles "Fu"...." force:100 goku, trunks「ジョン!!" force:1000
Vous pouvez passer la function dragonball
comme argument à la function hand_over
.
La "fonction dragonball" contient la "fusion de fonction interne", et la "fonction hand_over" reçoit la "fusion de fonction interne".
Notez que la fonction qui peut être passée (dans ce cas, hand_over ()
) ne fonctionne pas d'elle-même car d'autres fonctions peuvent exister.
Comme mentionné ci-dessus, la fonction ① Les fonctions sont affectées aux variables ② D'autres fonctions peuvent être définies dans la fonction ③ La fonction peut renvoyer la fonction ④ Vous pouvez passer une fonction à l'argument d'une certaine fonction Il a quatre propriétés telles que.
Le décorateur est une fonction définie en utilisant les propriétés de (2), (3) et (4) ci-dessus, et est utilisée en utilisant les propriétés de (1).
En d'autres termes, qu'est-ce qu'un décorateur? ** Une fonction qui reçoit la fonction A, ajoute des fonctions et renvoie une nouvelle fonction A_ver2.0. La fonction A_ver2.0 est utilisée en l'affectant à une variable. ** **
Lors de la création d'un décorateur
En conséquence, la fonction A_ver2.0 avec des fonctions ajoutées est née, et elle peut être utilisée sous la forme de X ()
.
(Je pensais que c'était similaire à Mixin dans la classe.)
def nom du décorateur(Où mettre la fonction décorée):
#Faire des arguments de longueur variable pour que tout argument de la fonction à décorer puisse être manipulé
décorateur def(*args, **kwargs):
#Appelez la fonction à décorer (vous pouvez utiliser la fonction d'origine telle quelle ou la modifier)
result = func(*args, **kwargs)
#Fonctions que vous souhaitez ajouter en décorant
décorateur de retour# <-Comprend des éléments décorés
def Fonction décorée()
une fonction
Variable pour stocker la nouvelle fonction décorée=Décorateur (fonction à décorer)
Variable pour stocker la nouvelle fonction décorée()
Supposons que vous ayez une fonction qui répertorie et affiche ce que vous souhaitez acheter.
Fonction get_fruits
def get_fruits(*args):
basket = []
for i in args:
basket.append(i)
print(basket)
get_fruits('apple','banana') # <- ['apple', 'banana']
Je vais décorer cela avec les tweets dans mon cœur.
Fonction get_fruits_ver2.0
#Décorateur
def deco(func): #④
def count(*args): #②
print('Quoi acheter')
func(*args)
print('Très bien, faisons ça')
return count #③
def get_fruits(*args):
basket = []
for i in args:
basket.append(i)
print(basket)
# get_fruits()Déco()Décorez avec
#Passez l'argument décorateur contenant la fonction que vous souhaitez décorer à la variable
#Si vous passez un argument à cette variable et l'exécutez, déco+ get_fonction fruits (obtenir_fruits_ver2.0) est exécuté
deco_get_fruits = deco(get_fruits) #①
deco_get_fruits('apple','banana')
#↑ Quoi acheter
# ['apple', 'banana']
#Très bien, faisons ça
En mettant l'objet de la fonction créée à l'aide du décorateur dans la variable (deco_get_fruits
), la version à fonction ajoutée de get_fruits peut être utilisée. De plus, en stockant l'objet de la fonction créée à l'aide du décorateur dans le nom de variable avec le même nom que la fonction décorée, il peut être écrasé par la fonction décorée.
get_fruits = deco(get_fruits)
get_fruits('apple','banana')
#↑ Quoi acheter
# ['apple', 'banana']
#Très bien, faisons ça
Comme mentionné ci-dessus, la fonction ver2.0 est créée en affectant la valeur de retour du décorateur à la variable, mais si vous utilisez l'expression décorateur
, vous n'avez pas à l'affecter à la variable une par une, et le code sera propre. ..
@Nom du décorateur
def Fonction décorée()
une fonction
Fonction décorée()
@deco
def get_vegetable(*args):
basket = []
for i in args:
basket.append(i)
print(basket)
get_vegetable('tomato','carrot')
#↑ Quoi acheter
# ['tomato', 'carrot']
#Très bien, faisons ça
En écrivant @decorator name
dans la ligne précédente de la définition de la fonction, la fonction définie directement ci-dessous est décorée et affectée au nom de la variable avec le même nom que cette fonction. En d'autres termes, le contenu de la variable sera écrasé par la fonction ver_2.0. Synonyme du code ci-dessous.
#Une variable avec le même nom que le nom de la fonction décorée=Décorateur (fonction à décorer)
get_vegitable = deco(get_vegetable)
Usage_2 est plus facile à voir que Usage_1. De cette façon, le contenu du traitement est le même, mais la syntaxe est simple et facile à lire. Elle s'appelle ** Syntax Sugar **.
Comme mentionné ci-dessus, si vous utilisez l'expression de décorateur, vous pouvez omettre l'affectation à la variable, et il semble que la lisibilité soit améliorée.
Le sujet principal de cet article, @ classmethod
, est également une expression de décorateur. Nous appelons la fonction intégrée classmethod ()
.
classmethod () a une fonction pour convertir la méthode définie dans la classe en une méthode de classe.
classmethod classmethod est une méthode qui peut être utilisée sans créer une instance de la classe. Il semble être utilisé lorsque vous souhaitez créer une instance après un traitement préalable dans la classe.
Par exemple, dans le module detetime, la méthode today de la classe de date est définie comme une méthode de classe, qui convertit le temps écoulé depuis l'époque (1er janvier 1970, 00:00:00) en heure locale et nécessite les informations nécessaires ( Année, mois, jour) doit être retourné.
module datetime aujourd'hui méthode de classe de date
class date:
#Abréviation
@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)
Afin de comprendre le code ci-dessus, je vais le réorganiser en phrases.
La méthode de classe today utilise la fonction time
du module intégré time
appelée _time pour attribuer le temps écoulé depuis l'époque (renvoyé la valeur 1576760183.8697512 lors de l'écriture de ce blog) à la variable t. .. Nous le transmettons comme argument à la méthode de classe fromtimestamp
.
Dans la méthode de classe fromtimestamp
, la variable t est placée dans la fonction localtime ()
du module de temps.
Si vous utilisez localtime ()
, les nombres de la variable t seront triés en mois, jours, secondes, etc. et stockés dans le taple, donc c'est facile à comprendre et pratique.
(Si vous utilisez localtime ()
sans argument, il obtiendra l'heure locale.)
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)
Chacun de ceux-ci est stocké dans les variables «y, m, d, hh, mm, ss, jour de la semaine, jday, dst», et finalement seulement «y», «m», «d» est renvoyé.
Par conséquent, vous pouvez obtenir l'année en cours y
mois m
jour d
en exécutant la méthode de classe today.
Je suis encore inexpérimenté, mais je n'ai pas saisi les mérites de la méthode de classe, mais personnellement, "Je veux initialiser la classe, mais le code devient compliqué, alors initialisez-le à un endroit autre que __init__
. Je l'ai arrangé pour qu'il soit utilisé quand je le veux. En regardant l'exemple pratique, il semble que le processus d'acquisition d'informations de l'extérieur soit défini dans la méthode de classe.
Quand je réfléchissais au code pour obtenir des informations de l'extérieur, j'ai écrit [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), j'ai donc écrit le code pour obtenir les informations météorologiques locales, je vais donc J'ai essayé de l'utiliser.
Un jeu pour deviner les prévisions météorologiques locales
import requests, xml.etree.ElementTree as ET, os
#Jeu pour deviner la probabilité de précipitations du jour
class Game(object):
ch = []
def __init__(self, am1, am2, pm1, pm2):
self.am1 = am1
self.am2 = am2
self.pm1 = pm1
self.pm2 = pm2
@classmethod
#Obtenez la probabilité de précipitations toutes les 6 heures à partir du Web 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]") #Nord et Sud
south = area[1] #Nœuds de la zone sud
info = south.findall('.//info[@date]') #7 jours dans le sud
today = info[0] #Noeud des minutes du sud d'aujourd'hui
period = today.findall('.//period[@hour]')
cls.ch = []
for percent in period:
cls.ch.append(percent.text)
return cls.ch
def quiz(self):
print(f'Ta Réponse-> [{self.am1}-{self.am2}-{self.pm1}-{self.pm2}] :Probabilité de précipitations d'aujourd'hui-> {Game.ch}')
play1 = Game(10,10,10,10)
play1.rain_percent()
play1.quiz() #Ta Réponse-> [10-10-10-10] :Probabilité de précipitations d'aujourd'hui-> ['0', '10', '40', '50']
Il est accessible à la fois depuis la classe et l'instance ↓
Game.rain_percent() # ['0', '10', '40', '50']
play1.rain_percent() # ['0', '10', '40', '50']
Il est recommandé que le premier argument de la méthode de classe soit cls
, et lorsqu'il est appelé comme nom de la classe.Méthode de classe () ʻou
nom de l'instance. méthode de classe (), cls aura
nom de classe` ou La «classe instanciée» est passée.
Comme mentionné ci-dessus, qu'est-ce que @classmethod?
Recommended Posts