2011-07-27 32 views
10

Tôi đã tự hỏi nếu bạn sử dụng trang trí @staticmethod trong mã của bạn.Có lợi ích gì khi sử dụng @staticmethod không?

Cá nhân tôi không sử dụng nó, vì phải mất nhiều chữ cái hơn để viết @staticmethod thì tự.

Lợi ích duy nhất (đến với tôi) khi sử dụng nó có thể rõ ràng hơn về mã, nhưng vì tôi thường viết mô tả phương pháp cho nhân sư, tôi luôn nêu rõ phương pháp đang sử dụng đối tượng hay không.

Hoặc có lẽ tôi nên bắt đầu sử dụng trang trí @staticmethod?

+0

Thực ra, tôi vẫn còn bối rối: Có một số nơi mà chúng ta phải sử dụng staticmethod trong python3 không? Tôi tìm thấy nhiều nơi không phải là cần thiết để sử dụng staticmethod. –

Trả lời

28

Có sử dụng @staticmethod hay không phụ thuộc vào những gì bạn muốn đạt được. Bỏ qua trang trí vì có nhiều thứ để nhập là một lý do khá ngớ ngẩn (không có hành vi phạm tội!) Và cho biết rằng bạn chưa hiểu khái niệm về phương pháp tĩnh tĩnh bằng Python!

Phương pháp tĩnh độc lập với lớp và bất kỳ cá thể lớp nào. Họ chỉ sử dụng phạm vi lớp như một không gian tên. Nếu bạn bỏ qua trang trí @staticmethod, bạn đang tạo một phương thức thể hiện không thể được sử dụng mà không xây dựng một cá thể.

Dưới đây là một lớp học rất đơn giản Foo:

>>> class Foo(object): 
... @staticmethod 
... def foo(): 
...  print 'foo' 
... 
... def bar(self): 
...  print 'bar' 

Bây giờ, Foo.foo() là một phương pháp tĩnh có thể được gọi trực tiếp:

>>> Foo.foo() 
foo 

Foo.bar() mặt khác là một phương pháp dụ , chỉ có thể được gọi từ các cá thể (đối tượng) của Foo:

>>> Foo.bar() 
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) 
>>> foo = Foo() 
>>> foo.bar() 
bar 

Để trả lời câu hỏi của bạn: Nếu bạn muốn xác định phương pháp tĩnh, hãy sử dụng @staticmethod. Nếu không, đừng.

Nếu bạn có phương thức không sử dụng self và do đó có thể được viết dưới dạng phương pháp tĩnh, hãy tự hỏi: Bạn có bao giờ muốn truy cập chức năng này từ bên ngoài mà không cần có một cá thể không? Hầu hết các lần, câu trả lời sẽ là: Số

+5

+1: "Bỏ qua trang trí vì có nhiều thứ để nhập là một lý do khá ngớ ngẩn". Thả lời xin lỗi. Thật ngớ ngẩn. –

+2

Chỉ cần thêm một lý do khác để sử dụng staticmethod thay vì tự - nó không chỉ cho python, mà còn cho các nhà duy trì trong tương lai. Nó làm nổi bật "hàm này không phụ thuộc vào trạng thái của lớp HOẶC một cá thể", trái ngược với classmethod hoặc một phương thức undecorated. Đối với một người bảo trì không quen thuộc với mã (ví dụ: bạn, 5 năm nữa tính từ thời điểm này) điều này làm cho việc học codebase nhanh hơn nhiều. –

+2

Cảm ơn câu trả lời của bạn, bây giờ khi tôi nhìn vào nó thực sự là một lý do ngớ ngẩn :) Tôi vẫn còn rất nhiều điều để học, nhưng nhờ các bạn học không đau như trước đây. – Michal

0

@staticmethod trang trí giúp bạn nhập và cải thiện khả năng đọc.

class Example: 
    @staticmethod 
    def some_method(): 
     return 

là giống như:

class Example: 
    def some_method(): 
     return 
    some_method = staticmethod(some_method) 

Tôi nghĩ rằng bạn có thể bị nhầm lẫn về những gì một phương pháp tĩnh là bằng Python như các thuật ngữ khác với ngôn ngữ khác. Một phương thức thông thường là "ràng buộc" với cá thể (self), một phương thức lớp là "ràng buộc" với lớp (cls) trong khi một phương thức tĩnh không bị ràng buộc (và không thể truy cập các thuộc tính instance và class.

Xem:

0

Giả sử rằng chúng ta muốn xác định abs phương thức trong lớp Math, sau đó chúng ta có hai lựa chọn:

class Math(): 
    def abs(n): 
     if n>0: 
      return n 
     else: 
      return -n 

class Math2(): 
    @staticmethod 
    def abs(n): 
     if n>0: 
      return n 
     else: 
      return -n 

Trong python2:

>>> Math.abs(-2) 
TypeError: unbound method abs() must be called with Math instance as 
first argument (got int instance instead) 

>>>Math().abs(-2) 
TypeError: abs() takes exactly 1 argument (2 given) 

>>> Math2.abs(-2) 
2 

>>> Math2().abs(-2) 
2 

python2 tự động chụp Math().abs(-2) như Math().abs(self,-2), do đó bạn phải sử dụng @staticmethod.

Trong Python3

>>>Math.abs(-3) 
3 

>>>Math().abs(-3) 
TypeError: abs() takes 1 positional argument but 2 were given 

>>>Math2.abs(-3) 
3 

>>>Math2().abs(-3) 
3 

Trong python3, bạn có thể sử dụng mà không cần classname.method() phương pháp tĩnh, nhưng nó sẽ nâng TypeError khi ai đó cố gắng sử dụng instance.method().

+0

điều này khác nhau giữa python2 và python3 làm cho tôi bối rối rất nhiều. –

Các vấn đề liên quan