อะไรเพียงแค่กดฉันมาจากทับทิมนั่นคือสิ่งที่เรียกว่าชั้นเรียนและวิธีการที่เรียกว่าอินสแตนซ์วิธีการเป็นเพียงฟังก์ชั่นที่มีความหมายความหมายนำไปใช้กับพารามิเตอร์ตัวแรกของ บริษัท ซึ่งถูกส่งผ่านไปอย่างเงียบ ๆ เมื่อฟังก์ชั่นที่เรียกว่าเป็นวิธีการของวัตถุ (เช่นobj.meth()
)
โดยปกติวัตถุนั้นจะต้องเป็นอินสแตนซ์ แต่ผู้@classmethod
ตกแต่งวิธีการเปลี่ยนกฎเพื่อส่งคลาส คุณสามารถเรียกวิธีการเรียนในตัวอย่าง (มันเป็นเพียงฟังก์ชั่น) - อาร์กิวเมนต์แรกจะเป็นชั้นเรียนของมัน
เนื่องจากเป็นเพียงฟังก์ชันจึงสามารถประกาศได้เพียงครั้งเดียวในขอบเขตที่กำหนด (เช่นclass
คำจำกัดความ) หากติดตามดังนั้นจะเป็นเรื่องแปลกสำหรับ Rubyist ที่คุณไม่สามารถมีคลาสและวิธีการอินสแตนซ์ที่มีชื่อเดียวกันได้
พิจารณาสิ่งนี้:
class Foo():
def foo(x):
print(x)
คุณสามารถโทรfoo
หาอินสแตนซ์
Foo().foo()
<__main__.Foo instance at 0x7f4dd3e3bc20>
แต่ไม่ใช่ในชั้นเรียน:
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)
ตอนนี้เพิ่ม@classmethod
:
class Foo():
@classmethod
def foo(x):
print(x)
การเรียกใช้อินสแตนซ์ผ่านคลาสนี้แล้ว:
Foo().foo()
__main__.Foo
เช่นเดียวกับการโทรในชั้นเรียน:
Foo.foo()
__main__.Foo
มันเป็นเพียงการประชุมที่กำหนดว่าเราใช้self
สำหรับอาร์กิวเมนต์แรกในวิธีการอินสแตนซ์และcls
ในวิธีการเรียน ฉันใช้ทั้งที่นี่เพื่อแสดงให้เห็นว่ามันเป็นเพียงข้อโต้แย้ง ใน Ruby self
เป็นคำหลัก
ตัดกับทับทิม:
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>
วิธีการระดับหลามเป็นเพียงฟังก์ชั่นการตกแต่งและคุณสามารถใช้เทคนิคเดียวกันเพื่อสร้างตกแต่งของคุณเอง วิธีการตกแต่งล้อมวิธีจริง (ในกรณีที่@classmethod
มันผ่านอาร์กิวเมนต์ระดับเพิ่มเติม) วิธีการพื้นฐานยังคงมีซ่อนอยู่แต่ยังคงสามารถเข้าถึงได้
เชิงอรรถ: ฉันเขียนสิ่งนี้หลังจากการปะทะกันของชื่อระหว่างวิธีการเรียนและอินสแตนซ์ทำให้ความอยากรู้ของฉันป่องๆ ฉันยังห่างไกลจากผู้เชี่ยวชาญ Python และต้องการแสดงความคิดเห็นหากสิ่งนี้ผิด