Ruby'den gelen sadece bana çarpan şey, sınıf yöntemi olarak adlandırılan bir örnek yöntem ve sözde örnek yönteminin, ilk parametresine uygulanan anlamsal anlamı olan bir işlev olması ve işlev bir yöntem olarak çağrıldığında sessizce geçmesidir . bir nesne (yani obj.meth()
).
Normalde bu nesne bir örnek olmalıdır ancak @classmethod
yöntem dekoratörü bir sınıfı geçmek için kuralları değiştirir. Bir örnek üzerinde bir sınıf yöntemi çağırabilirsiniz (bu sadece bir işlevdir) - ilk argüman kendi sınıfı olacaktır.
Bu sadece bir işlev olduğu için, herhangi bir kapsamda (yani class
tanım) yalnızca bir kez bildirilebilir . Bu nedenle, bir Rubyist için bir sürpriz olarak , bir sınıf yöntemine ve aynı ada sahip bir örnek yöntemine sahip olamayacağınıza dair .
Bunu düşün:
class Foo():
def foo(x):
print(x)
foo
Bir örneği arayabilirsiniz
Foo().foo()
<__main__.Foo instance at 0x7f4dd3e3bc20>
Ama bir sınıfta değil:
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)
Şimdi ekle @classmethod
:
class Foo():
@classmethod
def foo(x):
print(x)
Bir örneği çağırmak artık sınıfını geçer:
Foo().foo()
__main__.Foo
bir sınıfı çağırırken olduğu gibi:
Foo.foo()
__main__.Foo
Sadece self
bir örnek yönteminde ve cls
bir sınıf yönteminde bu ilk argüman için kullandığımızı belirleyen kural . İkisini de bunun sadece bir argüman olduğunu göstermek için kullandım. Ruby'de self
bir anahtar kelime.
Ruby ile kontrast:
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>
Python sınıfı yöntemi sadece dekore edilmiş bir işlevdir ve kendi dekoratörlerinizi oluşturmak için aynı teknikleri kullanabilirsiniz . Dekore edilmiş bir yöntem gerçek yöntemi sarar ( @classmethod
ek sınıf argümanını geçmesi durumunda ). Temel yöntem hala orada, gizli ama yine de erişilebilir .
footnote: Bunu bir sınıf ve örnek yöntemi arasındaki bir isim çakışmasından sonra merakımı uyandırdıktan sonra yazdım. Ben bir Python uzmanı olmaktan uzak ve bu yanlış varsa yorum istiyorum.