2013-08-15 81 views
28

Tôi đến từ một nền Java và tôi mới sử dụng python. Tôi có một vài kịch bản chia sẻ một số chức năng trợ giúp duy nhất cho ứng dụng liên quan đến đọc và ghi tệp. Một số chức năng liên quan đến việc đọc, một số có viết. Trong khi tìm kiếm các cách tiếp cận đúng, tôi thấy điều này: Static methods in Python?python - tôi có nên sử dụng các phương thức tĩnh hoặc các hàm mức cao nhất

Ông đề cập trong câu trả lời của mình:

Cuối cùng, sử dụng một cách tiết kiệm staticmethod! Có rất ít tình huống mà các phương thức tĩnh là cần thiết trong Python, và tôi đã thấy chúng được sử dụng nhiều lần trong đó một hàm "cấp cao nhất" riêng biệt sẽ rõ ràng hơn.

Tôi không hiểu các chức năng cấp cao nhất và tôi không chắc chắn ví dụ đơn giản này tốt hơn: 1) tạo lớp cho người đọc có chức năng đọc tĩnh và giống với người viết hoặc 2) để tuyên bố những người trợ giúp như các chức năng toàn cầu và tại sao?

EDIT: REALLY bài viết tốt về chủ đề này tôi chỉ tìm thấy http://tomayko.com/writings/the-static-method-thing

+2

Điều cần ghi nhớ là các chức năng cấp cao nhất trong python vẫn nằm trong phạm vi mô-đun (trừ khi bạn 'từ libfoo nhập *'). Nó ngăn chặn sự va chạm không gian tên mà bạn có với C, nhưng không phải đi đến các phương thức tĩnh lớp đầy đủ. –

+2

Cũng liên quan: http://stackoverflow.com/questions/12735392/python-class-static-methods – lmjohns3

+0

@ lmjohns3 - hoàn hảo. cảm ơn bạn. – Brad

Trả lời

36

Trong Java có các (IMHO sai) ý tưởng để sử dụng các lớp học ở khắp mọi nơi, thậm chí chỉ cần nhóm lại với nhau tĩnh chức năng mà không chia sẻ bất cứ tiểu bang (và do đó các lớp như vậy sẽ không bao giờ được khởi tạo).

Python ở đây cầu xin sự khác biệt; nếu bạn có các hàm không có một số trạng thái được chia sẻ (và do đó trong Java thường là các hàm static) và không liên quan chặt chẽ đến một lớp "thực" (= một lớp thực sự được khởi tạo), bạn chỉ cần sử dụng miễn phí chức năng bên trong một mô-đun. Lý do đằng sau điều này là một lớp chỉ cần thiết khi bạn thực sự muốn khởi tạo nó, do đó có một lớp giống như một thùng chứa cho một số hàm không cần chia sẻ một trạng thái cụ thể của cá thể là vô dụng.

Thực tế, bạn có thể phần nào nghĩ về mô-đun làm lớp static - nghĩa là một hàm chứa (= phương pháp tĩnh), biến mô-đun (= trường tĩnh) và các loại.

Điều tốt đẹp trong Python là có chức năng cấp cao nhất không đưa ra các vấn đề ô nhiễm không gian tên toàn cầu, vì trong các hàm/đối tượng cấp cao nhất của Python vẫn là mô-đun. Do đó, bạn vẫn có thể nhóm các chức năng theo mô-đun, không cần class -tax không cần thiết.


  1. trên thực tế, họ có thể có một số nhà nước chia sẻ, ở dạng của các biến mô-đun cấp (như vậy, độc thân); một lần nữa, các mô-đun tương tự-tĩnh lớp dường như giữ.
+0

ok. bạn có thể minh họa điều này với một ví dụ đơn giản trong python không? – Brad

+2

@Brad: uhm, tôi nên minh họa điều gì? Bạn chỉ cần không viết một lớp và đặt các định nghĩa hàm miễn phí ('def foo(): ...') bên trong tệp ... –

+0

uh ... hãy để tôi cập nhật câu hỏi của mình với những gì tôi nghĩ * bạn ' tái đề xuất – Brad

3

Nếu hàm có liên quan đến một lớp, thì hãy đặt nó làm phương pháp tĩnh. Ví dụ:

class DBobject(): 
    name = StringProperty() 

    @staticmethod 
    def get_by_name(name): 
     return db.select('select * from DBobject where name = "%s"' % name) 

python = DBobject.get_by_name('python') 

Tức là, phương pháp này hoàn toàn liên quan đến lớp DBobject nên nó phải là phương pháp tĩnh.

9

Từ Zen của Python (import this):

Namespaces are one honking great idea -- let's do more of those! 

Một trong những lý do chính để tạo ra phương pháp tĩnh trong một ngôn ngữ như Java là để đảm bảo rằng những phương pháp này không gió lên gây ô nhiễm không gian tên toàn cầu. Trong Python, tất cả các hàm "top-level" được đặt tự động trong vùng tên của module chứa các hàm đó, vì vậy không có nguy cơ gây ô nhiễm toàn cầu không gian tên theo cách này.

Nói cách khác, giống như nhiều ngôn ngữ khác, Python có thể tạo không gian tên theo một vài cách khác nhau. Trong trường hợp này, có rất ít nhu cầu tạo một lớp chỉ chứa các phương thức tĩnh, khi một mô-đun phục vụ cùng một mục đích định danh mà không có sự lộn xộn (hoặc tải nhận thức) liên quan đến việc định nghĩa một lớp.

+0

C++ là một ví dụ xấu, bởi vì nó có một cơ chế không gian tên độc lập với các lớp (tương tự như Python ở khía cạnh này, mặc dù rất khác nhau ở các lớp khác). – delnan

+0

@ delnan Hm, vâng, tôi biết ý bạn là gì - bạn có thể thay thế các lớp C++ chỉ chứa các phương thức tĩnh với một không gian tên, và vì những lý do tương tự như trong Python. Nhưng các vùng tên C++ không bị giới hạn tự động đối với một tệp đơn lẻ như hệ thống không gian tên mô-đun Python (hoặc giống như không gian tên thư mục của Java cho vấn đề đó). – lmjohns3

3

Đó là một câu hỏi về ô nhiễm không gian tên. Nếu bạn có một mô-đun với nhiều lớp và một số hàm chỉ có ý nghĩa đối với một lớp nhất định và các lớp con của nó, thì hãy tạo một phương thức tĩnh. Phương thức tĩnh có thể được gọi bằng cách sử dụng tên lớp hoặc bằng cách sử dụng một đối tượng của lớp.

>>> class A(object): 
...  @staticmethod 
...  def static_1(): 
...    print 'i am static' 
...  def a(self): 
...    self.static_1() 
... 
>>> A.static_1() 
i am static 
>>> a=A() 
>>> a.a() 
i am static 
>>> a.static_1() 
i am static 
>>> class B(A): 
...  pass 
... 
>>> b=B() 
>>> b.static_1() 
i am static 
>>> 
+0

+1 để đề cập đến thừa kế ('hậu duệ'). Có lẽ, nếu một người khác phân lớp này, bất kỳ phương pháp tĩnh nào sẽ được kế thừa và bất kỳ cấp cao nhất nào cũng không được. –

+0

@JCoombs - phải. Các phương thức tĩnh sẽ không được nhìn thấy bởi các lớp mở rộng chuỗi thừa kế để bạn khai báo chức năng cho lớp này và các lớp con của nó. Tài liệu là tự nhiên bởi vì các chuỗi tài liệu cho chúng sẽ chỉ hiển thị cho A và các con của nó. – tdelaney