Мне интересно, возможно ли создать метод, который ведет себя по-разному при вызове в качестве метода класса, чем при вызове в качестве метода экземпляра.
Например, в качестве проекта по повышению квалификации я пишу класс Matrix
(да, я знаю, что там уже есть очень хорошие матричные классы). Я создал для него метод класса с именем identity
, который возвращает единичную матрицу указанного размера.
Теперь, когда вызывается для экземпляра из Matrix
, кажется логичным, что размер указывать не нужно; он должен возвращать единичную матрицу того же размера, что и Matrix
, для которого она вызывается.
Другими словами, я хотел бы определить метод, который может определить, был ли он вызван через экземпляр и, если да, получить доступ к атрибутам этого экземпляра. К сожалению, даже после просмотра документации и нескольких поисков в Google я не нашел ничего, что бы предполагало, что это возможно. Кто-нибудь знает по-другому?
Edit:
Вау! Очевидно, я все еще не совсем привык к первоклассным функциям. Вот чем я закончил - спасибо Неизвестному за предоставленный ключ!
class Foo(object):
def __init__(self, bar):
self.baz = bar
self.bar = MethodType(lambda self: self.__class__.bar(self.baz), self, self.__class__)
@classmethod
def bar(cls, baz):
return 5 * baz
Foo.bar(3) # returns 15
foo = Foo(7)
foo.bar() # returns 35
Редактировать 2:
Просто небольшое замечание - этот метод (и большинство из представленных ниже) не будет работать с классами, которые определяют __slots__
, так как вы не можете переназначить метод.