2010-03-20 27 views
12

Tôi có phương thức riêng def __pickSide(self): trong lớp cha mà tôi muốn ghi đè trong lớp con. Tuy nhiên, lớp trẻ vẫn gọi là số def __pickSide(self): được kế thừa. Làm thế nào tôi có thể ghi đè lên chức năng? Tên hàm của lớp con giống hệt tên hàm của cha mẹ.Làm cách nào để ghi đè các hàm của lớp cha trong python?

+3

Vui lòng không sử dụng tất cả các '__' đó. Họ đang bối rối. Thực sự không có "riêng tư" trong Python. Họ làm cho những điều đơn giản trông khó hiểu. Vui lòng cập nhật câu hỏi của bạn bằng ví dụ nhỏ nhất về mã hiển thị sự cố của bạn. –

+0

Đó là mã tôi đang gặp rắc rối với ... bạn muốn gì hơn? Tôi biết rằng các hàm và biến "riêng tư" vẫn có thể được truy cập bằng Python, nhưng sẽ không sử dụng tất cả các hàm công cộng làm cho mọi thứ trở nên khó hiểu hơn khi sử dụng lớp? – wrongusername

+0

"Đó là mã"? Mã gì? Bạn có thể cập nhật câu hỏi để thực sự cung cấp mẫu mã thực tế thực sự không hoạt động không? Rất khó đoán mã của bạn trông như thế nào. Thật dễ dàng để giả định mọi thứ; thật dễ dàng để giả định sai. "Nhiều hơn những gì bạn muốn?" Mã. Để xem xét và xem những gì bạn đang thực sự sai lầm, không phải những gì sai lầm tôi giả sử bạn đang thực hiện. –

Trả lời

33

Hãy nhìn vào ví dụ đơn giản nhất:

from dis import dis 

class A(object): 
    def __pick(self): 
     print "1" 

    def doitinA(self): 
     self.__pick() 

class B(A): 
    def __pick(self): 
     print "2" 

    def doitinB(self): 
     self.__pick() 

b = B() 
b.doitinA() # prints 1 
b.doitinB() # prints 2 

dis(A.doitinA) 
print 
dis(B.doitinB) 

Các tháo được như sau:

8   0 LOAD_FAST    0 (self) 
       3 LOAD_ATTR    0 (_A__pick) 
       6 CALL_FUNCTION   0 
       9 POP_TOP 
      10 LOAD_CONST    0 (None) 
      13 RETURN_VALUE 

15   0 LOAD_FAST    0 (self) 
       3 LOAD_ATTR    0 (_B__pick) 
       6 CALL_FUNCTION   0 
       9 POP_TOP 
      10 LOAD_CONST    0 (None) 
      13 RETURN_VALUE 

Như bạn thấy, Python mangles tên hàm mà bắt đầu bằng hai dấu gạch dưới (và truy cập đến như vậy tên !!) với tên bao gồm tên lớp - trong trường hợp này là _A__pick_B__pick). Điều đó có nghĩa là lớp trong đó một hàm được xác định xác định phương thức nào của phương thức __pick được gọi.

Giải pháp đơn giản, tránh các phương pháp giả riêng tư bằng cách xóa dấu gạch dưới kép. Ví dụ: sử dụng _pick thay vì __pick.

5

Sự cố bạn thấy là dấu gạch dưới kép mangle tên hàm ngay cả trong cuộc gọi. Điều này ngăn cản tính đa hình hoạt động bình thường vì tên nó bị xáo trộn dựa trên tên của lớp mà phương thức được định nghĩa và không phải là tên của lớp của đối tượng đang được tham chiếu. Thay thế dấu gạch dưới kép bằng cái gì đó khác sẽ giải quyết vấn đề này.

3
  • sử dụng tên của phương pháp để làm cho việc truy cập trang này trở nên phức tạp hơn khi bạn cần. Tôi khuyên bạn không bao giờ sử dụng chúng, điều này làm cho những thứ như thử nghiệm diễn ra suôn sẻ hơn.

  • Không có riêng tư trong Python, và nếu có, nó sẽ ngăn bạn làm điều này bằng cách nào đó. (Đây là điểm thứ tư trong các ngôn ngữ mà có nó.)

  • Các quy ước chung để chỉ ra rằng một thuộc tính không phải là một phần của giao diện công cộng của một lớp nó sử dụng một hàng đầu đơn nhấn, như _foo . Điều này là đủ để làm cho mã của bạn rõ ràng tách chi tiết nội bộ khỏi API công khai của bạn.

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