Điều vừa xảy ra với tôi, đến từ Ruby, đó là một phương thức lớp được gọi là và phương thức cá thể được gọi là một hàm có ý nghĩa ngữ nghĩa được áp dụng cho tham số đầu tiên của nó, được truyền âm thầm khi hàm được gọi là phương thức một đối tượng (tức là obj.meth()
).
Thông thường đối tượng đó phải là một thể hiện nhưng trình @classmethod
trang trí phương thức thay đổi các quy tắc để truyền một lớp. Bạn có thể gọi một phương thức lớp trên một cá thể (nó chỉ là một hàm) - đối số đầu tiên sẽ là lớp của nó.
Bởi vì nó chỉ là một hàm , nó chỉ có thể được khai báo một lần trong bất kỳ phạm vi nào (nghĩa là class
định nghĩa). Do đó, nếu theo sau, gây bất ngờ cho Rubyist, rằng bạn không thể có một phương thức lớp và một phương thức cá thể có cùng tên .
Xem xét điều này:
class Foo():
def foo(x):
print(x)
Bạn có thể gọi foo
một ví dụ
Foo().foo()
<__main__.Foo instance at 0x7f4dd3e3bc20>
Nhưng không phải trên một lớp học:
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)
Bây giờ thêm @classmethod
:
class Foo():
@classmethod
def foo(x):
print(x)
Gọi một cá thể bây giờ vượt qua lớp của nó:
Foo().foo()
__main__.Foo
cũng như kêu gọi một lớp học:
Foo.foo()
__main__.Foo
Đó chỉ là quy ước chỉ ra rằng chúng ta sử dụng self
cho đối số đầu tiên đó trên một phương thức cá thể và cls
trên một phương thức lớp. Tôi đã không sử dụng ở đây để minh họa rằng đó chỉ là một đối số. Trong Ruby, self
là một từ khóa.
Tương phản với 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>
Phương thức lớp Python chỉ là một chức năng được trang trí và bạn có thể sử dụng các kỹ thuật tương tự để tạo ra các trang trí của riêng bạn . Một phương thức được trang trí bao bọc phương thức thực (trong trường hợp @classmethod
nó vượt qua đối số lớp bổ sung). Phương thức cơ bản vẫn còn đó, ẩn nhưng vẫn có thể truy cập .
chú thích: Tôi đã viết điều này sau khi một cuộc đụng độ tên giữa một lớp và phương thức cá thể khơi gợi sự tò mò của tôi. Tôi xa một chuyên gia Python và muốn bình luận nếu bất kỳ điều này là sai.