2009-03-28 7 views
26

Ví dụ:Có phải dạng xấu để gọi một classmethod như một phương thức từ một cá thể không?

Nếu tôi có một cái gì đó như thế này:

class C(object): 
    @classmethod 
    def f(cls, x): 
     return x + x 

này sẽ làm việc:

c = C() 

c.f(2) 
4 

Nhưng là hình thức xấu? nên tôi chỉ gọi

C.f() 

hoặc

c.__class__.f() 

Rõ ràng, điều này sẽ chỉ có ý nghĩa trong trường hợp f không tương tác với tự/CLS mong nó sẽ được lớp.

?

+1

OT, nhưng thích loại (c) c .__ class__ – Miles

Trả lời

25

Nếu bạn bị cám dỗ gọi phương thức lớp từ một cá thể, bạn có thể không cần phương thức lớp học.

Trong ví dụ bạn đưa ra một phương pháp tĩnh sẽ phù hợp hơn chính xác vì nhận xét cuối cùng của bạn (không có tương tác tự/cl).

class C(object): 
    @staticmethod 
    def f(x): 
     return x + x 

cách này đó là "phong độ tốt" để làm cả hai

c = C() 
c.f(2) 

C.f(2) 
+0

Có nhưng nếu bạn thực sự cần một phương pháp lớp học thì sao? – frnhr

4

Chủ yếu chỉ là tìm kiếm khó hiểu. Nếu tôi đang sử dụng lớp học của bạn và thấy điều này, nó sẽ làm cho tôi tự hỏi những gì bất ngờ khác là ở đó, nó chỉ trông giống như thiết kế xấu.

Có một lý do nào đó không chỉ là một staticmethod?

2

C.f() rõ ràng hơn c_instance.f()c_instance.__class__.f() chỉ là xấu xí. Kể từ khi rõ ràng và vẻ đẹp là những đặc điểm yêu thương đáng yêu trong cộng đồng python, tôi có xu hướng nói rằng C.f() là con đường tốt nhất.

Có lý do cụ thể nào mà bạn thậm chí muốn gọi theo một trong các cách khác không?

+4

Tên của lớp (trong trường hợp này 'C') có thể thay đổi mặc dù ... –

3

Nếu bạn có một thể hiện của C đã có, tại sao bạn cần f() là một phương thức lớp? Không chỉ là hình thức xấu, nó thường không cần thiết. Một người nào đó trên mạng nói: "Điều này là xấu bởi vì nó tạo ra ấn tượng rằng một số biến thể hiện trong đối tượng được sử dụng, nhưng đây không phải là trường hợp."

Mặc dù, trang 484 của learning python ghi chú rằng bạn có thể gọi phương thức một trong hai cách và nó sẽ được chính xác giống như miễn là bạn vượt qua những ví dụ tương tự trong.

+4

Bạn không cần classmethod-on-dụ cho mã ví dụ đã cho, nhưng nếu bạn bắt đầu subclassing C, bạn có thể. – bobince

9

tôi không nhớ sử dụng một classmethod như thế này từ bên ngoài lớp học, nhưng chắc chắn là ok đối với một phương thức thể hiện để gọi một classmethod trên chính nó (ví dụ: self.foo() trong đó foo là một classmethod). Điều này đảm bảo rằng kế thừa hoạt động như mong đợi và sẽ gọi .foo() trong lớp con bên phải thay vì lớp cơ sở.