2011-02-08 37 views
7

Hy vọng điều này là rõ ràng đủ:Python: Bắt giá trị baseclass từ lớp có nguồn gốc

class myParent(): 
    def __init__(self): 
     self.parentNumber = 5 

class Child(myParent): 
    def __init__(self): 
     self.childNumber = 4 

    def multiplyNumbers(self): 
     print myParent.parentNumber * self.childNumber 

p = Child() 
p.multiplyNumbers() 

tôi muốn thiết lập các parentNumber cá nhân, và sau đó đạt được con số thông qua các lớp con, và trong trường hợp này sử dụng nó cho một số phép nhân.

Tôi mới tham gia khu vực OOP nên mọi gợi ý chung về thừa kế cũng được hoan nghênh!

Thông tin thêm: Tôi đang thiết kế giải pháp quản lý dự án cho các dự án dựa trên vfx và đang chơi với các lớp học và kế thừa để xem cách chúng có thể giúp tôi nhiều nhất.

Ngay bây giờ, tôi đã có lớp học hàng đầu, Dự án và lớp học có nguồn gốc, Shot. Shot có biến self.length với độ dài của ảnh cụ thể. Nó cũng có phương thức getLengthInSeconds() sử dụng self.length cùng với Project.fps để xác định độ dài tính bằng giây. Project có một phương thức setFps() trong đó fps được thiết lập sau khi một cá thể của lớp được tạo ra.

Tôi đã quen với các biến được bắt đầu bằng tự. và đã không thử nghiệm nhiều với các lớp bằng cách sử dụng các biến "toàn cục" hơn mà không có bản thân. . Nếu tôi làm mọi thứ trên toàn cầu, không có bản thân. Tôi có thể sử dụng Project.fps mà không gặp rắc rối, nhưng tôi nhận được một cảnh báo "thực hành lập trình xấu" trong cổ của tôi. Có lẽ có một cách tốt hơn, gọn gàng hơn?

Edit:

Sau khi một số đọc sách, siêu() có vẻ kinda nguy hiểm, và hơn một chút hơn là tôi cần tôi nghĩ. Tôi chủ yếu có các lớp thừa kế đơn và thậm chí không chắc chắn làm thế nào để sử dụng phân cấp kim cương .. Có cách nào an toàn hơn để truy cập các biến siêu lớp và các phương thức không bao gồm siêu()?

Edit:

Allright, xem nếu điều này có ý nghĩa hoặc nếu tôi đang suy nghĩ về nó hoàn toàn sai.

Tôi đang xem các lớp và kế thừa là nhóm và trẻ em. Một đứa trẻ biết đó là cha mẹ và tất cả các giá trị của nó. Một đứa trẻ cho cha mẹ khác biết rằng giá trị của cha mẹ. Những gì tôi đang cố gắng để đạt được là có tất cả các bức ảnh được tạo ra là một phần của một dự án. Và ngay bây giờ, tôi đang tạo ra các cá thể Shot() từ bên trong lớp Project(), thêm các cá thể vào một danh sách các ảnh mà sau đó được duy trì trong cá thể Project().

tức

class myParent(object): 
    def __init__(self): 
     self.parent_id = '' 
     self.children = [] 

    def createChild(self, name): 
     self.children.append(myChild(name)) 

    def getChildren(self): 
     return self.children 

    def setParentId(self, id): 
     self.parentId = id 

class myChild(myParent): 
    def __init__(self, id): 
     super(myChild, self).__init__() 
     self.id = id 

    def getParentId(self): 
     return self.parent_id 

p = myParent() 
p.setParentId('parent01') 
p.createChild('child01') 
print p.getChildren()[0].getParentId() 

tôi có thể loại thấy mis-bước trong logic ở đây, nhưng không có cách nào thực xung quanh nó .. Có vẻ như mọi trẻ em được nhận một trường hợp mới của cha mẹ theo cách này, nơi parent_id luôn là một chuỗi rỗng.

+0

Bạn cần phải gọi constructor lớp cha. –

Trả lời

5
class myParent(object): 
    def __init__(self): 
     self.parentNumber = 5 

class Child(myParent): 
    def __init__(self): 
     myParent.__init__(self) 
     self.childNumber = 4 

    def multiplyNumbers(self): 
     print self.parentNumber * self.childNumber 

p = Child() 
p.multiplyNumbers()

Bạn thường có thể quản lý tốt mà không super khi bạn không có nhiều thừa kế hoặc các trường hợp biên giới khác , mặc dù nếu lớp cơ sở thay đổi, bạn sẽ cần phải nhớ thay đổi tên lớp cha từ init (và bất kỳ phương pháp nào khác đề cập đến myParent một cách rõ ràng).

Nếu bố mẹ của bạn __init__ nhận thông số, bạn cần chuyển chúng từ số __init__ của trẻ.

class myParent(object): 
    def __init__(self, customParam): 
     self.parentNumber = 5 
     self.customParam = customParam 

class Child(myParent): 
    def __init__(self, customParam): 
     myParent.__init__(self, customParam) 
     self.childNumber = 4

Nếu bạn không thích sự lặp lại của customParam trong mọi tầng lớp trẻ, có một mô hình thay thế OO gọi hai xây dựng giai đoạn, trong đó hoạt động như thế này:

class myParent(object): 
    def customInit(self, customParam): 
     self.parentNumber = 5 
     self.customParam = customParam 

class Child(myParent): 
    def __init__(self, customParam): 
     self.childNumber = 4 

p = Child() 
p.customInit(10) 
p.multiplyNumbers() 

Trong mô hình này, bạn không cần để lặp lại bất kỳ tham số nào của cha mẹ, hoặc thậm chí gọi số __init__ của cha mẹ, nhưng nhược điểm là bạn sẽ cần phải nhớ luôn gọi hàm khởi tạo thứ cấp khi tạo đối tượng hoặc đối tượng của bạn sẽ bị bỏ sót một phần.

CẬP NHẬT (để trả lời câu hỏi được cập nhật):

Bạn dường như đang trộn lẫn hai khái niệm không liên quan về làm cha mẹ ở đây. Thừa kế là về phân cấp kiểu, và bạn dường như sau một hệ thống phân cấp quyền sở hữu (là-a so với có-a).

tôi sẽ cấu trúc mã cập nhật của bạn như thế này:

class myParent(object): 
    def __init__(self, parentId): 
     self.id = parentId 
     self.children = [] 

    def createChild(self, name): 
     self.children.append(myChild(name, self)) 

    def getChildren(self): 
     return self.children 

class myChild(object): 
    def __init__(self, childId, parent): 
     self.id = childId 
     self.parent = parent 

    def getParentId(self): 
     return self.parent.id 

p = myParent('parent01') 
p.createChild('child01') 
print p.getChildren()[0].getParentId()
+0

Cảm ơn câu trả lời của bạn! Bạn có nhớ xem câu hỏi được cập nhật không? –

+0

@Marcus: đã cập nhật câu trả lời – shang

+0

Có, điều đó có ý nghĩa hơn nhiều. Cảm ơn! –

5

Bạn chỉ cần yêu cầu Child để chạy khởi tạo từ myParent. Sau đó, phiên bản hiện tại (self) tất cả các thuộc tính thể hiện một thể hiện của myParent sẽ có ("is a"), vì vậy bạn có thể sử dụng self.parentNumber. Bạn làm như vậy bằng cách đặt super(Child, self).__init__() vào Child.__init__ (lý tưởng, trên dòng đầu tiên) - myParent.__init__(self) sẽ hoạt động, nhưng có thể sai (theo cách tinh tế) khi lớp cơ sở thay đổi hoặc trong trường hợp đa thừa kế. Bạn có thể thả tất cả các đối số vào super nếu bạn đang sử dụng Python 3.

Cũng lưu ý rằng

class C(object): 
    x = ... 

rất khác so với

class C(object): 
    def __init__(self): 
     self.x = ... 

Cựu tạo ra một biến lớp học, mà được chia sẻ bởi tất cả các trường của C. Sau này tạo ra một biến cá thể, mỗi cá thể của C có riêng nó. (Tương tự như vậy, các biến toàn cầu không bị ràng buộc vào các instance - nhưng tôi giả sử bạn đang nói về việc trên?)

+1

+1 .. và nó phải là 'self.parentNumber' trong' multiplyNumbers'. – sdolan

+0

@sdolan: Có, bao gồm. – delnan

+0

Chỉ là loại thông tin tôi đang tìm kiếm. Tôi se thử no. –

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