Я думаю, что Стивен на самом деле прав . Чтобы ответить на исходный вопрос, затем, чтобы настроить метод класса, просто предположите, что первый аргумент не будет вызывающим экземпляром, а затем убедитесь, что вы вызываете метод только из класса.
(Обратите внимание, что этот ответ относится к 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)