2011-02-08 14 views
7

आशा यह पर्याप्त स्पष्ट है:पायथन: व्युत्पन्न वर्ग से baseclass मान रही

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() 

मैं व्यक्तिगत रूप से parentNumber स्थापित करने के लिए, और उसके बाद बच्चे कक्षा के माध्यम से उस नंबर तक पहुँचते हैं, और इस मामले में यह कुछ के लिए उपयोग इच्छा गुणन।

मैं ओओपी क्षेत्र में नया हूं इसलिए विरासत पर किसी भी सामान्य संकेतक का भी स्वागत है!

और जानकारी: मैं VFX आधारित परियोजनाओं के लिए एक परियोजना प्रबंधन समाधान डिजाइनिंग रहा हूँ, और देखने के लिए कैसे वे मेरी मदद कर सकते सबसे वर्गों और विरासत के साथ खेल रहा हूँ।

अभी, मुझे शीर्ष श्रेणी, परियोजना, और एक व्युत्पन्न कक्षा, शॉट मिला है। शॉट में विशिष्ट शॉट की लंबाई के साथ एक self.length चर है। इसे getLengthInSeconds() विधि भी मिलती है जो सेकेंड में लंबाई निर्धारित करने के लिए Project.fps के साथ self.length का उपयोग करती है। प्रोजेक्ट में एक setFps() विधि है जिसमें कक्षा के उदाहरण के बाद fps सेट किया गया है।

मैं स्वयं के साथ prefixed चर के लिए उपयोग किया जाता है। और स्वयं के बिना अधिक "वैश्विक" चर का उपयोग कर कक्षाओं के साथ बहुत अधिक प्रयोग नहीं किया है। । अगर मैं सबकुछ वैश्विक बना देता हूं, कोई स्वयं नहीं।, मैं बिना किसी परेशानी के Project.fps का उपयोग कर सकता हूं, लेकिन मुझे अपने गर्दन में "खराब प्रोग्रामिंग अभ्यास" चेतावनी मिल रही है। शायद एक बेहतर, अधिक साफ, रास्ता है?

संपादित करें:

कुछ पढ़ने के बाद, सुपर() थोड़े खतरनाक लगता है, और थोड़ा अधिक की तुलना में मैं मुझे लगता है कि जरूरत है। मेरे पास मुख्य रूप से सिंगल-विरासत कक्षाएं हैं और यह भी सुनिश्चित नहीं है कि डायमंड पदानुक्रमों का उपयोग कैसे किया जाए .. क्या सुपरक्लास वैरिएबल और विधियों तक पहुंचने का कोई सुरक्षित तरीका है जिसमें सुपर() शामिल नहीं है?

संपादित करें:

Allright, देख अगर यह समझ में आता है या अगर मैं यह सब गलत के बारे में सोच रहा हूँ।

मैं कक्षाओं और विरासत समूहों और बच्चों के रूप में देख रहा हूं। एक बच्चा जानता है कि यह माता-पिता और उसके सभी मूल्य हैं। एक बच्चे को दूसरे माता-पिता को पता है कि माता-पिता मूल्यवान हैं। जो मैं पूरा करने की कोशिश कर रहा हूं वह सभी शॉट्स को एक परियोजना का हिस्सा बन रहा है। और अभी, मैं प्रोजेक्ट() कक्षा के भीतर से शॉट() उदाहरण बना रहा हूं, उदाहरणों को परियोजनाओं() उदाहरण के भीतर बनाए गए शॉट्स की सूची में उदाहरण जोड़ रहा हूं।

यानी

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() 

मैं इन सबसे छुटकारा तर्क यहाँ में गलत कदम, लेकिन यह चारों ओर कोई असली तरीका देख सकते हैं .. लगता है जैसे हर बच्चे को माता-पिता का एक नया उदाहरण इस तरह से हो रही है जहां, parent_id हमेशा एक खाली स्ट्रिंग है।

+0

आप सुपर क्लास निर्माता कॉल करने के लिए की जरूरत है। –

उत्तर

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()

आप आमतौर पर super बिना ठीक प्रबंधन कर सकते हैं आप एक से अधिक विरासत या अन्य सीमा मामलों की जरूरत नहीं है जब , हालांकि यदि बेस क्लास बदलती है, तो आपको init (और कोई अन्य विधि जो स्पष्ट रूप से मेरे माता-पिता को संदर्भित करती है) से पैरेंट क्लास नाम बदलने की याद रखना होगा।

यदि आपके माता-पिता के __init__ पैरामीटर लेते हैं, तो आपको उन्हें बच्चे के __init__ से पास करने की आवश्यकता है।

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

आप सभी बच्चे कक्षाओं में customParam की पुनरावृत्ति नापसंद करते हैं, तो एक विकल्प OO पैटर्न दो चरण निर्माण कहा जाता है, जो इस तरह काम करता है:

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() 

इस पद्धति में, आप की जरूरत नहीं है किसी भी माता-पिता के पैरामीटर को दोहराने के लिए, या बच्चे में माता-पिता के __init__ को भी कॉल करें, लेकिन नकारात्मकता यह है कि ऑब्जेक्ट्स बनाते समय आपको हमेशा द्वितीयक कन्स्ट्रक्टर को कॉल करना याद रखना होगा, या आपकी ऑब्जेक्ट आंशिक रूप से अनियमित हो जाएगी।

अद्यतन (अपडेट सवाल का जवाब देने):

आप यहाँ अपने पिता होने के दो असंबंधित अवधारणाओं मिश्रण कर रहे हैं। विरासत प्रकार पदानुक्रम के बारे में है, और आप एक स्वामित्व पदानुक्रम के बाद होने लगते हैं (एक बनाम है-ए)।

मैं इस तरह अपने अपडेट किए गए कोड संरचना होगा:

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

आपके उत्तर के लिए धन्यवाद! क्या आप अपडेट किए गए प्रश्न पर नजर डालेंगे? –

+0

@Marcus: उत्तर – shang

+0

अपडेट किया गया हां, जो अधिक समझ में आता है। धन्यवाद! –

5

आपको myParent से प्रारंभ करने के लिए बस Child बताना होगा। उसके बाद, वर्तमान उदाहरण (self) में सभी उदाहरण विशेषता myParent के उदाहरण हैं ("is a"), तो आप self.parentNumber का उपयोग कर सकते हैं। super(Child, self).__init__()Child.__init__ (आदर्श रूप से, पहली पंक्ति पर) - myParent.__init__(self) काम करके काम करेगा, लेकिन बेस क्लास में परिवर्तन होने पर या एकाधिक विरासत के मामले में यह गलत हो सकता है (सूक्ष्म तरीके से)। यदि आप पाइथन 3 का उपयोग कर रहे हैं तो आप super पर सभी तर्क छोड़ सकते हैं।

भी ध्यान रखें कि

class C(object): 
    x = ... 

से

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

पूर्व बहुत अलग है एक वर्ग चर, जो C के सभी उदाहरणों द्वारा साझा किया जाता है। उत्तरार्द्ध एक आवृत्ति चर बनाते हैं, C के प्रत्येक उदाहरण में यह स्वयं का है। (इसी तरह, वैश्विक चर के उदाहरणों के लिए बाध्य नहीं कर रहे हैं - लेकिन मैं आप ऊपर के बारे में बात कर रहे थे मान?)

+1

+1 .. और यह 'mult.plyNumbers'' multiplyNumbers' में होना चाहिए। – sdolan

+0

@sdolan: हाँ, शामिल है। – delnan

+0

बस जिस तरह की जानकारी मैं खोज रहा था। मैं इसे आज़माउंगा। –

संबंधित मुद्दे