Reputation: 108
I was wondering how I can make all instances inherited from dataObj (Two and One) modify the .data
attribute of self.buffer
:
When I modify the .data of the instance of one or two, I want this to change the .data of the buffer instance.
In order word, how can I make .data
become global for all instance of dataObj
so when I change .data
in one of the instance it apply changes for all of them.
class dataObj():
def __init__(self, data):
self.data = data
def read(self, width):
self.data = self.data[width:]
class One(dataObj):
def __init__(self, data):
self.data = data
def deserialize(self):
self.read(1)
class Two(dataObj):
def __init__(self, data):
self.data = data
def deserialize(self):
self.read(2)
class msg():
def __init__(self):
self.buffer = dataObj('0123456789')
def run(self):
print("buffer.data = ", self.buffer.data)
one = One(self.buffer.data)
one.deserialize()
print("one.data = ",one.data)
two = Two(self.buffer.data)
two.deserialize()
print("two.data = ", two.data)
print("buffer.data = ", self.buffer.data)
main = msg()
main.run()
The output:
buffer.data = 0123456789
one.data = 123456789
two.data = 23456789
buffer.data = 0123456789
The output I want:
buffer.data = 0123456789
one.data = 123456789
two.data = 3456789
buffer.data = 3456789
I have to think of using a class attribute something like this:
class dataObj():
data = '0123456789'
def __init__(self, data):
pass
But I dont know how i may modify this class attribute.
Upvotes: 2
Views: 58
Reputation: 6891
Using a separate class, as suggested here is probably a better idea but if you are dead set on trying to do it with class methods it can be achieved as:
class dataObj():
data = None
@classmethod
def read(cls, width):
dataObj.data = dataObj.data[width:]
class One(dataObj):
@classmethod
def deserialize(cls):
dataObj.read(1)
class Two(dataObj):
@classmethod
def deserialize(cls):
dataObj.read(2)
class msg():
def __init__(self):
dataObj.data = '0123456789'
self.buffer = dataObj()
def run(self):
print("buffer.data = ", self.buffer.data)
one = One()
one.deserialize()
print("one.data = ",one.data)
two = Two()
two.deserialize()
print("two.data = ", two.data)
print("buffer.data = ", self.buffer.data)
main = msg()
main.run()
Here all subclasses are updating the same class variable defined in dataObj()
.
Upvotes: 1
Reputation: 114481
In Python str
objects are immutable; so after
a = 'hello world'
b = a
there's nothing you can do to b
to change the value of a
; the only way to change the value of a
is to reassign a
.
If for buffer instead you use a mutable object (e.g. a list
) then you need two simple changes:
def read(self, width):
self.data[:] = self.data[width:] # note the [:] part
...
self.buffer = dataObj(list('0123456789')) # list
One key point is that the statement
self.data[:] = self.data[width:]
is different from a simple assignment because it will mutate the list content and the other instance will see the changes.
Writing instead
self.data = self.data[width:]
creates a new list object with the remaining part, without touching the original list object pointed to by the other instance.
With those two changes the output becomes:
buffer.data = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
one.data = ['1', '2', '3', '4', '5', '6', '7', '8', '9']
two.data = ['3', '4', '5', '6', '7', '8', '9']
buffer.data = ['3', '4', '5', '6', '7', '8', '9']
Upvotes: 2
Reputation: 859
You can try this
class data:
val = ''
def __init__(self, value):
data.val = value
def printval(self):
print(self.val)
Now the variable val is shared between all the instances.
d1 = data('addingfromd1')
d1.printval()
d2 = data('addingfromd2')
d1.printval() --> This will print latest value "addingfromd2"
Upvotes: 1