2011-10-18 40 views
6

Tôi có một số mã hướng đối tượng trong Python, nơi một số lớp được mở rộng để cung cấp các bit mã tùy chỉnh bị mất (a la Template Method pattern, nhưng cũng có các biến), sẽ chỉ được sử dụng bởi lớp siêu, chứ không phải bởi mã máy khách sử dụng chúng.Quy ước đặt tên Python cho các thuộc tính và phương thức có nghĩa là được ghi đè

Có bất kỳ công ước phong cách cho ví dụ trừu tượng (hay ngu si đần độn, bởi vì thực hiện của họ trong lớp siêu sẽ là một trong hai pass hay nâng cao một NonImplemented ngoại lệ) phương pháp và các thuộc tính?

Tôi đã duyệt qua PEP-0008 và nó chỉ đề cập đến việc thêm một dấu gạch dưới vào số riêng thành viên không có ý định được sử dụng bởi các lớp con.

+1

Quy ước là ghi lại nó trong tài liệu cho lớp, theo như tôi biết ... Tôi không nghĩ có một quy ước cụ thể nào khác ngoài điều đó. –

Trả lời

9

Trước hết tôi nghĩ rằng bạn đang nhầm lẫn khi bạn nói rằng:

về prepending nhấn mạnh cho các thành viên cá nhân không nhằm mục đích được sử dụng bởi các lớp con.

Thực tế việc thêm phương thức/thuộc tính bằng dấu gạch dưới là quy ước python có nghĩa là phương thức/thuộc tính này không được truy cập bên ngoài lớp (và phân lớp của nó) và tôi nghĩ bạn quên đọc về dấu gạch dưới kép được sử dụng để tạo phương thức/thuộc tính không thể ghi đè.

class Foo(object): 
    def __foo(self): 
     print "foo" 
    def main(self): 
     self.__foo() 


class Bar(Foo): 
    def __foo(self): 
     print "bar" 


bar = Bar() 
bar.main() 
# This will print "foo" and not "bar". 

Có một cách khác để bày tỏ ý phương pháp sơ khai bằng cách đó là sử dụng abc.ABCMetaabc.abstractmethod.

11

Tôi thường sử dụng dấu gạch dưới đơn, ví dụ: _myvar cho các phương pháp/thuộc tính được bảo vệ (như trong C++), có thể được sử dụng bởi các lớp dẫn xuất và sử dụng dấu gạch dưới kép, ví dụ: __var khi nó không nên được sử dụng bởi bất kỳ ai khác, và như hai gạch dưới tên ở cấp độ định nghĩa lớp là mangled, vì vậy chúng không thể bị ghi đè trong lớp dẫn xuất, ví dụ:

class A(object): 
    def result1(self): # public method 
     return self._calc1() 

    def result2(self): # public method 
     return self.__calc2() 

    def _calc1(self): # protected method, can be overridden in derived class 
     return 'a1' 

    def __calc2(self): # private can't be overridden 
     return 'a2' 


class B(A): 
    def _calc1(self): 
     return 'b1' 

    def __calc2(self): 
     return 'b2' 

a = A() 
print a.result1(),a.result2() 
b = B() 
print b.result1(),b.result2() 

Ở đây nó dường như có nguồn gốc lớp B là trọng cả _calc1__calc2 nhưng __calc2 không được ghi đè bởi vì tên của nó đã được đọc sai với tên lớp và do đó sản lượng là

a1 a2 
b1 a2 

thay vì

a1 a2 
b1 b2 

nhưng cuối cùng chọn bất kỳ quy ước và tài liệu nào, cũng trong trường hợp trên nó không phải là tha lớp t cơ sở không có thể ghi đè tư nhân, đây là một cách :)

class B(A): 
    def _calc1(self): 
     return 'b1' 

    def _A__calc2(self): 
     return 'b2' 
2

Không thực sự có quy ước đặt tên cho các phương thức này vì chúng sẽ có cùng tên khi chúng được ghi đè. Nếu không, họ sẽ không bị ghi đè! Tôi nghĩ rằng có phương pháp để được ghi đè làm điều gì đó tầm thường, và ghi lại nó cho phù hợp, là đủ tốt:

class MyClass: 

    def aMethod(): 
    '''Will be overridden in MyDerivedClass''' 
    pass 

Tên mangling, mà bạn đề cập đến trong câu hỏi của bạn, rất hữu ích nếu bạn có một phương pháp không tầm thường mà sẽ bị ghi đè, nhưng bạn vẫn muốn có thể truy cập phiên bản cơ sở.Xem the documentation để biết thêm thông tin và ví dụ.

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