Quand je faisais un résumé qui servait également de mémorandum à ici, je l'ai remarqué ou découvert à nouveau, alors je voudrais le décrire ici.
Un exemple qui produit "Hello World". Définissez respectivement la variable de classe c_var
et la variable d'instance ʻi_var`.
class Test(object):
c_var = "Hello"
def __init__(self):
self.i_var = "World"
def __str__(self):
return Test.c_var + " " + self.i_var
print(Test())
Validé avec un modèle qui définit une variable d'instance avec le même nom qu'une variable de classe (ʻexamine1) et un modèle qui modifie une variable de classe (ʻexamine2
).
class Test(object):
c_var = "Hello"
def __init__(self):
self.i_var = "World"
def __str__(self):
return Test.c_var + " " + self.i_var
def examine1(self):
self.c_var = "Hey"
return self
def examine2(self):
Test.c_var = "Hey"
return self
t = Test()
print(t.examine1())
print(t.examine2())
print(Test())
À partir du résultat de sortie, on peut voir que la variable de classe et la variable d'instance sont différentes, et la variable d'instance peut être modifiée.
Résultat de sortie
Hello World
Hey World
Hey World
Vous pouvez vérifier la variable d'instance avec vars (t)
et la variable de classe avec vars (Test)
.
Maintenant, essayez de changer les variables de classe avec des méthodes de classe et statiques au lieu de méthodes. A partir du résultat de la sortie, les deux __init__
sont appelés et les variables de classe ont été modifiées.
class Test(object):
c_var = "Hello"
def __init__(self):
self.i_var = "World"
def __str__(self):
return Test.c_var + " " + self.i_var
@classmethod
def class_method(cls):
cls.c_var = "Class"
@staticmethod
def static_method():
Test.c_var = "Static"
Test.class_method()
print(Test())
Test.static_method()
print(Test())
Résultat de sortie
Class World
Static World
Examinons maintenant les changements dans les variables de classe et les variables d'instance lors de la création de copies superficielles et profondes. Même dans une copie complète, la valeur de la variable de classe a changé.
import copy
class Test(object):
c_var = 2
def __init__(self, obj):
self.i_var = obj
def __str__(self):
return "{0} {1}".format(Test.c_var, self.i_var)
def examine1(self):
self.i_var += 2
return self
def examine2(self):
Test.c_var += 2
return self
a = int(3)
t1 = Test(a)
t1.examine1().examine2()
print(t1)
print(Test(a))
print("--- shallow copy ---")
t2 = copy.copy(t1)
t2.examine1().examine2()
print(t1)
print(t2)
print(Test(a))
print("--- deep copy ---")
t3 = copy.deepcopy(t1)
t3.examine1().examine2()
print(t1)
print(t2)
print(t3)
print(Test(a))
Résultat de sortie
4 5
4 3
--- shallow copy ---
6 5
6 7
6 3
--- deep copy ---
8 5
8 7
8 7
8 3
self
Une classe qui définit deux méthodes, ʻexamine1 et ʻexamine2
.
class Test(object):
def __init__(self):
self.i_var = "nothing"
def __str__(self):
return self.i_var
def examine1(self):
self.i_var = "examine1"
return self
def examine2(self):
self.i_var = "examine2"
return self
t1 = Test()
print(t1)
print(t1.examine1())
print(t1.examine2())
Le résultat de sortie est le suivant.
Résultat de sortie
nothing
examine1
examine2
Ici, quand j'ai exécuté print (Test.examin1 ())
comme une méthode de classe, bien sûr j'ai eu une erreur.
Erreur
examine1() missing 1 required positional argument: 'self'
Est-il donc possible de spécifier une instance dans le premier argument «self»?
t1 = Test()
print(Test.examine1(t1.examine2()))
print(Test.examine2(t1.examine1()))
Lorsque ce qui précède a été exécuté, le résultat suivant a été produit.
Résultat de sortie
examine1
examine2
Summary m'a présenté une classe appelable, et en même temps j'étais parfaitement conscient de mon manque d'étude.
class Callable(int):
def __call__(self, *arguments):
print(arguments[0])
a = Callable(5)
print(a)
a(3)
Résultat de sortie
5
3
Ce qui précède signifie que ʻapeut être utilisé à la fois comme une fonction et comme une variable. Puisque la valeur de référence de l'instance
Callable est affectée à ʻa
, la valeur passée en argument lors de la création de l'instance est affichée par print (a)
. De plus, quand ʻaest appelé comme une fonction,
call est appelé, donc la valeur du premier argument est
print`.
Une implémentation qui étend ʻint en appelable et gère le premier argument comme une unité (nom) dans un appel de fonction. Remplacement de la classe standard ʻint
par ʻint = Callable`.
class Callable(int):
def __call__(self, unit):
print("{0} {1}".format(self, unit))
int = Callable
print(int("3") * 4)
int("5")("meters")
int(2017 - 2010)("years old")
12
5 meters
7 years old
Nous avons préparé une classe qui implémente __add__
et __sub__
. La valeur de référence ne change pas même si elle est ajoutée ou soustraite comme indiqué ci-dessous. Cela a également remplacé le standard «int». La valeur de «id» n'a pas changé après le remplacement.
class MyInt(object):
def __init__(self, v):
self.__v = v
def __add__(self, other):
self.__v += other
return self
def __sub__(self, other):
self.__v -= other
return self
a = int(2)
print(id(a))
a = a + 3
print(id(a))
a = a - 5
print(id(a))
int = MyInt
a = int(3)
print(id(a))
a = a + 3
print(id(a))
a = a - 5
print(id(a))
1983644176
1983644272
1983644112
1736248227544
1736248227544
1736248227544
__mul__
, __matmul__
, __truediv__
, __floordiv__
, __mod__
, __divmod__
, __pow__
, __lshift__
, __rshift__
, __and__
, `_xor Mettez en œuvre en conséquence.
J'ai utilisé ʻint` dans la vérification des variables de classe et des variables d'instance (n ° 3), mais j'ai essayé de vérifier en utilisant l'objet numérique mutable défini ici. Comme pour les variables immuables, la valeur des variables de classe peut être modifiée même avec une copie complète.
import copy
class MyInt(object):
def __init__(self, v):
self.__v = v
def __str__(self):
return str(self.__v)
def __add__(self, other):
self.__v += other
return self
def __sub__(self, other):
self.__v -= other
return self
int = MyInt
class Test(object):
c_var = int(2)
def __init__(self, obj):
self.i_var = obj
def __str__(self):
return "{0} {1}".format(Test.c_var, self.i_var)
def examine1(self):
self.i_var += 2
return self
def examine2(self):
Test.c_var += 2
return self
a = int(3)
t1 = Test(a)
t1.examine1().examine2()
print(t1)
print(Test(a))
print("--- shallow copy ---")
t2 = copy.copy(t1)
t2.examine1().examine2()
print(t1)
print(t2)
print(Test(a))
print("--- deep copy ---")
t3 = copy.deepcopy(t1)
t3.examine1().examine2()
print(t1)
print(t2)
print(t3)
print(Test(a))
Résultat de sortie
4 5
4 5
--- shallow copy ---
6 7
6 7
6 7
--- deep copy ---
8 7
8 7
8 9
8 7
Recommended Posts