To, co właśnie mnie uderzyło, wywodzące się z Ruby, to fakt, że tak zwana metoda klasowa i tak zwana metoda instancji jest tylko funkcją o znaczeniu semantycznym zastosowaną do jej pierwszego parametru, który jest cicho przekazywany, gdy funkcja jest wywoływana jako metoda obiekt (tj obj.meth()
).
Zwykle ten obiekt musi być instancją, ale @classmethod
dekorator metod zmienia reguły przekazywania klasy. Możesz wywołać metodę klasy na instancji (to tylko funkcja) - pierwszym argumentem będzie jej klasa.
Ponieważ jest to tylko funkcja , można ją zadeklarować tylko raz w dowolnym zakresie (tj. class
Definicji). Dlatego też, jako niespodzianka dla Rubyist, że nie możesz mieć metody klasy i metody instancji o tej samej nazwie .
Rozważ to:
class Foo():
def foo(x):
print(x)
Możesz zadzwonić foo
do instancji
Foo().foo()
<__main__.Foo instance at 0x7f4dd3e3bc20>
Ale nie na zajęciach:
Foo.foo()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unbound method foo() must be called with Foo instance as first argument (got nothing instead)
Teraz dodaj @classmethod
:
class Foo():
@classmethod
def foo(x):
print(x)
Wywołanie instancji przechodzi teraz przez jej klasę:
Foo().foo()
__main__.Foo
podobnie jak wzywanie klasy:
Foo.foo()
__main__.Foo
Jest to tylko konwencja, która nakazuje, abyśmy używali self
tego pierwszego argumentu w metodzie instancji i cls
metodzie klasy. Nie użyłem żadnego z nich, aby zilustrować, że to tylko argument. W Ruby self
jest słowem kluczowym.
Porównaj z Ruby:
class Foo
def foo()
puts "instance method #{self}"
end
def self.foo()
puts "class method #{self}"
end
end
Foo.foo()
class method Foo
Foo.new.foo()
instance method #<Foo:0x000000020fe018>
Metoda klasy Python jest tylko dekorowaną funkcją i możesz używać tych samych technik do tworzenia własnych dekoratorów . Udekorowana metoda otacza prawdziwą metodę (w przypadku, @classmethod
gdy przekazuje dodatkowy argument klasy). Podstawowa metoda jest nadal dostępna, ukryta, ale nadal dostępna .
przypis: Napisałem to po konflikcie nazw między metodą klasy a instancji, która wzbudziła moją ciekawość. Jestem daleki od eksperta w Pythonie i chciałbym komentować, jeśli którekolwiek z nich jest złe.