2011-10-20 34 views
13

Tôi muốn một phương thức trong một lớp cơ sở để gọi một phương thức khác trong cùng một lớp thay vì phương thức ghi đè trong một lớp kế thừa. Tôi muốn đoạn mã sau để in raPhương thức thừa kế và lớp cơ sở gọi là python

Class B: 6

Class A: 9

này có thể được thực hiện?


# Base class definition 
class ClassA(object): 
    def __init__(self): 
     print("Initializing A") 

    # hoping that this function is called by this class's printFnX 
    def fnX(self, x): 
     return x**2 

    def printFnX(self, x): 
     print("ClassA:",self.fnX(x)) 

# Inherits from ClassA above 
class ClassB(ClassA): 
    def __init__(self): 
     print("initizlizing B") 

    def fnX(self, x): 
     return 2*x 

    def printFnX(self, x): 
     print("ClassB:", self.fnX(x)) 
     ClassA.printFnX(self,x) 

bx = ClassB() 
bx.printFnX(3) 
+10

Bạn có quan tâm xem xét lại câu trả lời nào bạn đã đánh dấu là được chấp nhận không? lựa chọn hiện tại thực sự là lời khuyên xấu cho hầu hết mọi người và hầu hết các trường hợp sử dụng. –

Trả lời

-3

Điều tương tự cũng có thể đạt được bằng cách thực hiện fnXprintFnX cả hai phép đo lớp.

class ClassA(object): 

    def __init__(self): 
     print("Initializing A") 

    # hoping that this function is called by this class's printFnX 
    @classmethod 
    def fnX(self, x): 
     return x ** 2 

    @classmethod 
    def printFnX(self, x): 
     print("ClassA:",self.fnX(x)) 

class ClassB(ClassA): 
    def __init__(self): 
     print("initizlizing B") 

    def fnX(self, x): 
     return 2*x 

    def printFnX(self, x): 
     print("ClassB:", self.fnX(x)) 
     ClassA.printFnX(x) 


bx = ClassB()<br> 
bx.printFnX(3) 
+0

Điều này tốt hơn câu trả lời khác ... thanh lịch hơn. Cảm ơn. – fodon

+5

Điều này thậm chí không hoạt động. Cố gắng truy cập một biến ví dụ như '' self.y'' từ bên trong fnX. Trong một classmethod, biến * self * không còn giữ instance; thay vào đó, nó trở thành lớp của cá thể người gọi, vì vậy bạn đã hoàn toàn mất quyền truy cập vào các biến mẫu. "Mẫu" này là một thảm họa và một cái gì đó không nên được sử dụng trong mã mà bạn quan tâm. –

+0

Tôi đồng ý, nó chỉ trả lời câu hỏi ban đầu của anh ấy, đó là tất cả những hạn chế mà bạn vừa mô tả. Không có mẫu nào ở đây. –

49

Xin chúc mừng, bạn đã khám phá ra trường hợp sử dụng động cơ thúc đẩy cho tên đúp gạch Python của mangling :-)

Đối với các chi tiết và một ví dụ làm việc ra xem: http://docs.python.org/tutorial/classes.html#private-variables và tại http://docs.python.org/reference/expressions.html#atom-identifiers.

Dưới đây là làm thế nào để sử dụng nó ví dụ của bạn:

# Base class definition 
class ClassA(object): 
    def __init__(self): 
     print("Initializing A") 

    # hoping that this function is called by this class's printFnX 
    def fnX(self, x): 
     return x**2 
    __fnX = fnX 

    def printFnX(self, x): 
     print("ClassA:",self.__fnX(x)) 

# Inherits from ClassA above 
class ClassB(ClassA): 
    def __init__(self): 
     print("initizlizing B") 

    def fnX(self, x): 
     return 2*x 

    def printFnX(self, x): 
     print("ClassB:", self.fnX(x)) 
     ClassA.printFnX(self,x) 

bx = ClassB() 
bx.printFnX(3) 

Các trường hợp sử dụng được mô tả như là một cách thực hiện Open-Closed Principle trong "The Art of subclassing" được tìm thấy tại http://www.youtube.com/watch?v=yrboy25WKGo&noredirect=1.

+1

Rất sâu sắc. Bây giờ tôi biết cách đặt tên của các phương thức kép là hữu ích cho! –

+0

Điều có thể không rõ ràng là các phương thức trong lớp cơ sở phải là công khai hoặc bạn phải sử dụng tên đầy đủ. Python không có vòng loại "được bảo vệ" hoặc "bạn", vì vậy khi tái cấu trúc chỉ đơn giản là di chuyển 'def __doSomething (self): 'từ lớp siêu thành lớp cơ sở sẽ không làm cho nó có thể truy cập được từ lớp siêu. Bạn sẽ phải làm cho nó công khai 'def doSomething (self): 'hoặc sử dụng tên bị xé. –

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