Я думаю, что Стивен на самом деле прав . Чтобы ответить на исходный вопрос, затем, чтобы настроить метод класса, просто предположим, что первый аргумент не будет вызывающим экземпляром, а затем убедитесь, что вы вызываете метод только из класса.
(Обратите внимание, что этот ответ относится к Python 3.x. В Python 2.x вы получите TypeError
для вызова метода для самого класса.)
Например:
class Dog:
count = 0 # this is a class variable
dogs = [] # this is a class variable
def __init__(self, name):
self.name = name #self.name is an instance variable
Dog.count += 1
Dog.dogs.append(name)
def bark(self, n): # this is an instance method
print("{} says: {}".format(self.name, "woof! " * n))
def rollCall(n): #this is implicitly a class method (see comments below)
print("There are {} dogs.".format(Dog.count))
if n >= len(Dog.dogs) or n < 0:
print("They are:")
for dog in Dog.dogs:
print(" {}".format(dog))
else:
print("The dog indexed at {} is {}.".format(n, Dog.dogs[n]))
fido = Dog("Fido")
fido.bark(3)
Dog.rollCall(-1)
rex = Dog("Rex")
Dog.rollCall(0)
В этом коде метод «rollCall» предполагает, что первый аргумент не является экземпляром (как если бы он был вызван экземпляром вместо класса). Пока «rollCall» вызывается из класса, а не экземпляра, код будет работать нормально. Если мы попытаемся вызвать «rollCall» из экземпляра, например:
rex.rollCall(-1)
, это приведет к возникновению исключения, потому что он отправит два аргумента: сам и -1 и «rollCall», определяется только для принятия одного аргумента.
Кстати, rex.rollCall () отправляет правильное количество аргументов, но также вызывает возбуждение исключения, поскольку теперь n будет представлять экземпляр Dog (т. е. , rex), когда функция ожидает, что число n будет численным.
Здесь происходит декорация: если мы предшествуем методу «rollCall» с
@staticmethod
, то, явно заявив, что метод является статическим, мы можем даже назвать его из экземпляра. Теперь
rex.rollCall(-1)
будет работать. Вставка @staticmethod перед определением метода затем останавливает экземпляр от отправки себя в качестве аргумента.
Вы можете проверить это, попробовав следующий код с и без строки @staticmethod, прокомментированной.
class Dog:
count = 0 # this is a class variable
dogs = [] # this is a class variable
def __init__(self, name):
self.name = name #self.name is an instance variable
Dog.count += 1
Dog.dogs.append(name)
def bark(self, n): # this is an instance method
print("{} says: {}".format(self.name, "woof! " * n))
@staticmethod
def rollCall(n):
print("There are {} dogs.".format(Dog.count))
if n >= len(Dog.dogs) or n < 0:
print("They are:")
for dog in Dog.dogs:
print(" {}".format(dog))
else:
print("The dog indexed at {} is {}.".format(n, Dog.dogs[n]))
fido = Dog("Fido")
fido.bark(3)
Dog.rollCall(-1)
rex = Dog("Rex")
Dog.rollCall(0)
rex.rollCall(-1)