I have a basic question regarding inheritance (in python). I have two classes, and one of them inherits from the other, for example
class p: def __init__(self,name): self.pname = name class c(p): def __init__(self,name): self.cname = name
Is there a chance that I can create a parent and several child objects that are related to the SAME-parent? It should work so that the parent contains several variables, and whenever I access the corresponding variables from the child, I actually refer to the variable, the form of the parent. That is, if I changed it for one child, it will be changed also for all other children, and the data will be stored only once in memory (and will not be copied for each child ...)
Thanks in advance.
Here is a possible workaround that I don't find so enjoyable
class P: def __init__(self, name): self.pname = name class C: def __init__(self, name,pobject): self.pobject = pobject self.cname = name
Is this really a modern state or are there other concepts?
Sebastian
Thanks to everyone for helping me, also with conventions :) But I'm still not very happy. Perhaps I am giving a more advanced example to emphasize what I really want to do.
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
Now I can do the following
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'
And this is exactly what I want. There is a variable name that is different for each child, and the parent class accesses the individual variables. Normal inheritance. Then there is the variable data that comes from the parent class, and each child gets access to it. However now no longer works
In [39]: c1.data = "tst" In [40]: c2.data Out[40]: 'shareddata' In [41]: c1.data Out[41]: 'tst'
I want the change in c1.data to affect c2.data as well, since I want the variable to be split, like a global variable of this parent class.
And more than that. I also want to create different instances of P, each of which has its own data variable. And when I create a new C object, I want to indicate from which data the P object should be inhetited, i.e. shared ....
UPDATE:
Check out @eyquem's comment: Thanks for that, it is heading in the direction I want. However, now __class__.pvar is shared between all objects in the class. I want multiple P instances to have another pvar. Suppose P1 has pvar = 1 and P2 has pvar = 2. Then I want to create child elements C1a, C1b, C1c that are connected to P1, that is, if I say that C1a.pvar should remove pvar from P1. Then I create C2a, C2b, C2c, and if I get access, i.e. C2b.pvar, I want to access pvar from P2. Since class C inherits pvar from class P pvar, it is known to C. My naive idea is that if I create a new CI instance, you must specify which (existing) P-object should be used as the parent object, and not create a completely new P object, as is done when P.__init__ inside __init__ C ... It sounds simple to me, maybe I forgot something ...
UPDATE:
So, I found this discussion , which is pretty much my question.
Any suggestions?
UPDATE:
The class ._ subclasses_ method no longer exists.
UPDATE:
Here is another link:
discussion link
There he is solved by copying. But I do not want to copy the parent class, because I would like it to exist only once ...
UPDATE:
I apologize for yesterday's discussion, I'm a little sick ... And thanks for the messages! Now I will read them. I thought about it a little more, and here is a possible solution that I found
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):
This is a bit cumbersome, and I hope there is an easier way to achieve this. But it does have a function that pvar is only mentioned in class P, and class C does not know about pvar, since this should be according to my understanding of inheritance. However, when I create a new instance of C, I can specify an existing instance of P to be stored in the pobject variable. When the pvar variable is actually accessed, pvar from the P instance stored in this variable is available ...
Output is determined
3078326816 3078326816 3078326816 3074996544 3074996544 3074996544 3078326816 3074996544 156582944 156583040 156583200 156583232 156583296 156583360
Now I will read your last comments,
all the best, Sebastian
UPDATE:
I think the most elegant way would be the following (which DOES NOT work)
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
I think python should consider this ...
UPDATE:
Ok, now I have found a way to achieve this, thanks to the explanations of eyquem. But since this is really a hack, there must be an official version for the same ...
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)
the conclusion is the same as above
3077745184 3077745184 3077745184 3074414912 3074414912 3074414912 3077745184 3074414912 144028416 144028448 144028480 144028512 144028544 144028576
UPDATE: even if the identifier seems correct, the last code does not work, as is clear from this test
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
he has a way out
newpvar1 1 1 2 2 2 1 2
However, the first version I posted works:
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):
with exit
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
Does anyone know why this is so? I probably don't understand the internal way that python works with this __dict__ so well ...