Is it possible in Python to have two objects, each of them an instance of a different class, that always share the same value for a particular attribute?
For instance, suppose the following code:
class A(): def __init__(self): self.attrA = "attrA" self.grid = None def init_grid(self, x): self.grid = x class B(): def __init__(self): self.attrB = "attrB" self.grid = None def init_grid_as_preexisting(self, pre_grid): self.grid = pre_grid a = A() a.init_grid([1,2,3]) b = B() b.init_grid_as_preexisting(a.grid) print("a.grid, b.grid = ", a.grid, b.grid) # OUT: a.grid, b.grid = [1, 2, 3] [1, 2, 3] a.grid = [4,5,6] print("a.grid, b.grid = ", a.grid, b.grid) # OUT: a.grid, b.grid = [4, 5, 6] [1, 2, 3] b.grid = [7,8,9] print("a.grid, b.grid = ", a.grid, b.grid) # OUT: a.grid, b.grid = [4, 5, 6] [7, 8, 9]
Here my goal would be for a.grid
and b.grid
to contain the same value always, regardless of whether one is initialized from the other or which one is modified; the desired output would be then:
a.grid, b.grid = [1, 2, 3] [1, 2, 3] a.grid, b.grid = [4, 5, 6] [4, 5, 6] a.grid, b.grid = [7, 8, 9] [7, 8, 9]
In this question it is suggested to use a base class containing a class attribute, and use a static method to modify the desired shared attribute. I would rather not use this solution as I don’t want to have this attribute shared among all instances always, only when it is strictly desired. From this other question, I guess I could use the Mutable Default Argument property to have a shared value for a given parameter, but again, I don’t always want the parameter to be shared.
In short, is it possible to have two objects, each an instance of two different classes, to have a shared parameter?
Advertisement
Answer
You can have a parent class to hold the data:
class GridHolder: def __init__(self): self.grid = None class A: def __init__(self, grid_holder: GridHolder): self.attrA = "attrA" self.grid_holder = grid_holder @property def grid(self): return self.grid_holder.grid @grid.setter def grid(self, value): self.grid_holder.grid = value class B: def __init__(self, grid_holder: GridHolder): self.attrB = "attrB" self.grid_holder = grid_holder @property def grid(self): return self.grid_holder.grid @grid.setter def grid(self, value): self.grid_holder.grid = value data_holder = GridHolder() a = A(data_holder) a.grid = [1, 2, 3] b = B(data_holder) print("a.grid, b.grid = ", a.grid, b.grid) # OUT: a.grid, b.grid = [1, 2, 3] [1, 2, 3] a.grid = [4, 5, 6] print("a.grid, b.grid = ", a.grid, b.grid) # OUT: a.grid, b.grid = [4, 5, 6] [1, 2, 3] b.grid = [7, 8, 9] print("a.grid, b.grid = ", a.grid, b.grid) # OUT: a.grid, b.grid = [4, 5, 6] [7, 8, 9]
Output:
a.grid, b.grid = [1, 2, 3] [1, 2, 3] a.grid, b.grid = [4, 5, 6] [4, 5, 6] a.grid, b.grid = [7, 8, 9] [7, 8, 9]