In Python-Klassen gibt es drei Arten von Methoden.
@ classmethod
. Das erste Argument ist obligatorisch und wird üblicherweise auf "cls" gesetzt.@ staticmethod
. Das Argument ist nicht erforderlich.class C:
val = 20
def __init__(self):
self.val = 1
def normal_method(self, v):
return self.val + v + 2
@classmethod
def class_method(cls, v):
return cls.val + v + 3
@staticmethod
def static_method(v):
return C.val + v + 4
i = C()
i.normal_method(5) # i.val + 5 + 2 = 1 + 5 + 2 = 8
i.class_method(6) # C.val + 6 + 3 = 20 + 6 + 3 = 29
i.static_method(7) # C.val + 7 + 4 = 20 + 7 + 4 = 31
C.normal_method(5) # requires 2 args but 1: error
C.normal_method(i, 6) # i.val + 6 + 2 = 1 + 6 + 2 = 9
C.normal_method(C, 7) # C.val + 7 + 2 = 20 + 7 + 2 = 29
C.class_method(8) # C.val + 8 + 3 = 20 + 8 + 3 = 31
C.static_method(9) # C.val + 9 + 4 = 20 + 9 + 4 = 33
Normale Methoden sind immer noch Funktionen.
Wenn man dies als Gegenprodukt betrachtet, kann das Verhalten durch das erste Argument geändert werden.
class C:
#Hinzu kommt
def trick_method(arg, v):
if isinstance(arg, C):
return arg.val * 2 * v
else:
return C.val + arg * v
i.trick_method(4) # i.val * 2 * 4 = 1 * 2 * 4 = 8
C.trick_method(5) # requires 2 args but 1: error
C.trick_method(6, 7) # C.val + 6 * 7 = 20 + 6 * 7 = 62
C.trick_method(i, 8) # i.val * 2 * 8 = 1 * 2 * 8 = 16
C.trick_method(C, 9) # C.val + C * v: error
Das obige "trick_method ()" verhält sich wie eine normale Methode über eine Instanz und wie eine statische Methode über eine Klasse.
Wenn das Verhalten anders ist, sollte es normalerweise eine andere Methode sein.
Ich habe mir beim Erstellen einer Klasse, die Instanzen als Gruppe verwaltet, eine so seltsame Verwendung ausgedacht.
class Student:
rooms = {}
def __init__(self, room):
self.myroom = room
if not room in Student.rooms:
Student.rooms [room] = []
Student.rooms [room].append(self)
def classmates(self_or_room):
if isinstance(self_or_room, Student):
self = self_or_room
for s in Student.rooms[self.myroom]:
if s != self:
yield s
elif self_or_room in Student.rooms:
room = self_or_room
return iter(Student.rooms[room])
Ann = Student('3-A')
Bob = Student('3-B')
Cathy = Student('3-B')
Dan = Student('3-A')
Ellen = Student('3-A')
Fred = Student('3-B')
mates_of_ann = Ann.classmates() # Dan, Ellen
mates_of_3A = Student.classmates('3-A') # Ann, Dan, Ellen
mates_of_bob = Bob.classmates() # Cathy, Fred
mates_of_3B = Student.classmates('3-B') # Bob, Cathy, Fred
Diese Methode kann nicht mit Methoden mit Dekoratoren verwendet werden (z. B. "@ property" oder "@ classmethod").
Recommended Posts