Note that there are some explanatory texts on larger screens.

plurals
  1. PObasic inheritance (in python)
    primarykey
    data
    text
    <p>users, </p> <p>I have a basic question concerning inheritance (in python). I have two classes and one of them is inherited from the other like</p> <pre><code>class p: def __init__(self,name): self.pname = name class c(p): def __init__(self,name): self.cname = name </code></pre> <p>Is there any possibility that I can create a parent object and several child objects which refer to the SAME parent object? It should work like that that the parent object contains several variables and whenever I access the corresponding variables from a child I actually access the variable form the parent. I.e. if I change it for one child it is changed also for all other childes and the data are only stored once in memory (and not copied for each child...)</p> <p>Thank you in advance.</p> <p>Here is a possible workaround which I do not consider as so nice</p> <pre><code>class P: def __init__(self, name): self.pname = name class C: def __init__(self, name,pobject): self.pobject = pobject self.cname = name </code></pre> <p>Is this really the state of the art or do there exist other concepts?</p> <p>Sebastian</p> <p>Thank you all for helping me, also with the name conventions :) But I am still not very satisfied. Maybe I give a more advanced example to stress what I really want to do.</p> <pre><code>class P: data = "shareddata" def __init__(self,newdata): self.data = newdata def printname(self): print self.name class C(P): def __init__(self,name): self.name = name </code></pre> <p>Now I can do the following</p> <pre><code>In [33]: c1 = test.C("name1") In [34]: c2 = test.C("name2") In [35]: c1.printname() name1 In [36]: c2.printname() name2 In [37]: c1.data Out[37]: 'shareddata' In [38]: c2.data Out[38]: 'shareddata' </code></pre> <p>And this is so far exactly what I want. There is a variable name which is different for every child and the parent class accesses the individual variables. Normal inheritance. Then there is the variable data which comes from the parent class and every child access it. However, now the following does not work any more</p> <pre><code>In [39]: c1.data = "tst" In [40]: c2.data Out[40]: 'shareddata' In [41]: c1.data Out[41]: 'tst' </code></pre> <p>I want the change in c1.data to affect also c2.data since I want the variable to be shared, somehow a global variable of this parent class. </p> <p>And more than that. I also want to create different instances of P, each having its own data variable. And when I create a new C object I want to specify from which P object data should be inhetited i.e. shared....</p> <p>UPDATE: </p> <p>remark to the comment of @eyquem: Thanks for this, it is going into the direction I want. However, now the <code>__class__.pvar</code> is shared among all objects of the class. What I want is that several instances of P may have a different pvar. Lets assume P1 has pvar=1 and P2 has pvar=2. Then I want to create children C1a, C1b, C1c which are related to P1, i.e. if I say C1a.pvar it should acess pvar from P1. Then I create C2a, C2b, C2c and if I access i.e. C2b.pvar I want to access pvar from P2. Since the class C inherits pvar from the class P pvar is known to C. My naive idea is that if I create a new instance of C I should be able to specify which (existing) P object should be used as the parent object and not to create a completely new P object as it is done when calling <code>P.__init__</code> inside of the <code>__init__</code> of C... It sounds simple to me, maybe I forget something...</p> <p>UPDATE:</p> <p>So I found <a href="http://www.velocityreviews.com/forums/t356880-can-you-create-an-instance-of-a-subclass-with-an-existing-instance-of-the-base-class.html" rel="nofollow">this discussion</a> which is pretty much my question</p> <p>Any suggestions?</p> <p>UPDATE:</p> <p>The method .<strong>class</strong>._<em>subclasses</em>_ seems to be not existing any more..</p> <p>UPDATE:</p> <p>Here is onother link:</p> <p><a href="http://bytes.com/topic/python/answers/834541-using-existing-instance-parent" rel="nofollow">link to discussion</a></p> <p>There it is solved by copying. But I do not want to copy the parent class since I would like that it exists only once...</p> <p>UPDATE:</p> <p>Sorry for leaving the discussion yesterday, I am a bit ill... And thank you for the posts! I will now read through them. I thought about it a bit more and here is a possible solution I found</p> <pre><code>class P(object): def __init__(self,pvar): self.pobject = None self._pvar = pvar @property def pvar(self): if self.pobject != None: return self.pobject.pvar else: return self._pvar @pvar.setter def pvar(self,val): if self.pobject != None: self.pobject.pvar = val else: self._pvar=val def printname(self): print self.name class C(P): def __init__(self,name,pobject): #&lt;-- The same default `P()` is # used for all instances of `C`, # unless pobject is explicitly defined. P.__init__(self,None) self.name = name self.pobject = pobject p1 = P("1") p2 = P("2") c1a = C("c1a",p1) c1b = C("c1b",p1) c1c = C("c1c",p1) c2a = C("c2a",p2) c2b = C("c2b",p2) c2c = C("c2c",p2) print id(c1a.pvar) print id(c1b.pvar) print id(c1c.pvar) print id(c2a.pvar) print id(c2b.pvar) print id(c2c.pvar) print id(p1.pvar) print id(p2.pvar) print id(c1a.name) print id(c1b.name) print id(c1c.name) print id(c2a.name) print id(c2b.name) print id(c2c.name) </code></pre> <p>It is a bit cumbersome and I hope that there is a simpler way to achieve this. But it has the feature that pvar is only mentioned in the class P and the class C does not know about pvar as it should be according to my understanding of inheritance. Nevertheless when I create a new instance of C I can specify an existing instance of P which will be stored in the variable pobject. When the variable pvar is accessed actually pvar of the P-instance stored in this variable is accessed... </p> <p>The output is given by</p> <pre><code>3078326816 3078326816 3078326816 3074996544 3074996544 3074996544 3078326816 3074996544 156582944 156583040 156583200 156583232 156583296 156583360 </code></pre> <p>I will read now through your last comments,</p> <p>all the best, Sebastian </p> <p>UPDATE:</p> <p>I think the most elegant way would be the following (which DOES NOT work)</p> <pre><code>class P(object): def __init__(self,pvar): self.pvar = pvar def printname(self): print self.name class C(P): def __init__(self,name,pobject): P = pobject self.name = name </code></pre> <p>I think python should allow for this...</p> <p>UPDATE:</p> <p>Ok, now I found a way to achieve this, due to the explanations by eyquem. But Since this is really a hack there should be an official version for the same...</p> <pre><code>def replaceinstance(parent,child): for item in parent.__dict__.items(): child.__dict__.__setitem__(item[0],item[1]) print item class P(object): def __init__(self,pvar): self.pvar = pvar def printname(self): print self.name class C(P): def __init__(self,name,pobject): P.__init__(self,None) replaceinstance(pobject,self) self.name = name p1 = P("1") p2 = P("2") c1a = C("c1a",p1) c1b = C("c1b",p1) c1c = C("c1c",p1) c2a = C("c2a",p2) c2b = C("c2b",p2) c2c = C("c2c",p2) print id(c1a.pvar) print id(c1b.pvar) print id(c1c.pvar) print id(c2a.pvar) print id(c2b.pvar) print id(c2c.pvar) print id(p1.pvar) print id(p2.pvar) print id(c1a.name) print id(c1b.name) print id(c1c.name) print id(c2a.name) print id(c2b.name) print id(c2c.name) </code></pre> <p>the output is the same as above</p> <pre><code>3077745184 3077745184 3077745184 3074414912 3074414912 3074414912 3077745184 3074414912 144028416 144028448 144028480 144028512 144028544 144028576 </code></pre> <p>UPDATE: Even if the id's seem to be right, the last code does not work as is clear from this test</p> <pre><code>c1a.pvar = "newpvar1" print c1a.pvar print c1b.pvar print c1c.pvar print c2a.pvar print c2b.pvar print c2c.pvar print p1.pvar print p2.pvar </code></pre> <p>it has the output </p> <pre><code>newpvar1 1 1 2 2 2 1 2 </code></pre> <p>However the version I posted first works:</p> <pre><code>class P(object): def __init__(self,pvar): self.pobject = None self._pvar = pvar @property def pvar(self): if self.pobject != None: return self.pobject.pvar else: return self._pvar @pvar.setter def pvar(self,val): if self.pobject != None: self.pobject.pvar = val else: self._pvar=val def printname(self): print self.name class C(P): def __init__(self,name,pobject): #&lt;-- The same default `P()` is # used for all instances of `C`, # unless pobject is explicitly defined. P.__init__(self,None) self.name = name self.pobject = pobject p1 = P("1") p2 = P("2") c1a = C("c1a",p1) c1b = C("c1b",p1) c1c = C("c1c",p1) c2a = C("c2a",p2) c2b = C("c2b",p2) c2c = C("c2c",p2) print id(c1a.pvar) print id(c1b.pvar) print id(c1c.pvar) print id(c2a.pvar) print id(c2b.pvar) print id(c2c.pvar) print id(p1.pvar) print id(p2.pvar) print id(c1a.name) print id(c1b.name) print id(c1c.name) print id(c2a.name) print id(c2b.name) print id(c2c.name) print "testing\n" c1a.printname() c1b.printname() c1c.printname() c2a.printname() c2b.printname() c2c.printname() print "\n" c1a.name = "c1anewname" c2b.name = "c2bnewname" c1a.printname() c1b.printname() c1c.printname() c2a.printname() c2b.printname() c2c.printname() print "pvar\n" print c1a.pvar print c1b.pvar print c1c.pvar print c2a.pvar print c2b.pvar print c2c.pvar print p1.pvar print p2.pvar print "\n" c1a.pvar = "newpvar1" print c1a.pvar print c1b.pvar print c1c.pvar print c2a.pvar print c2b.pvar print c2c.pvar print p1.pvar print p2.pvar print "\n" c2c.pvar = "newpvar2" print c1a.pvar print c1b.pvar print c1c.pvar print c2a.pvar print c2b.pvar print c2c.pvar print p1.pvar print p2.pvar </code></pre> <p>with the output</p> <pre><code>3077745184 3077745184 3077745184 3074414912 3074414912 3074414912 3077745184 3074414912 144028416 144028448 144028480 144028512 144028544 144028576 testing c1a c1b c1c c2a c2b c2c c1anewname c1b c1c c2a c2bnewname c2c pvar 1 1 1 2 2 2 1 2 newpvar1 newpvar1 newpvar1 2 2 2 newpvar1 2 newpvar1 newpvar1 newpvar1 newpvar2 newpvar2 newpvar2 newpvar1 newpvar2 </code></pre> <p>Does anybody know why it is like that? I probably do not understand the internal way python works with this <code>__dict__</code> so well...</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload