Can I keep a list of references, that auto update in the list?
Question:
In its essence, I do this:
a = True
b = False
ls = [a, b]
a = False
print(ls)
> [True, False]
And what happens is that whatever happens to a
is decoupled from the list after the first inclusion. Is there any way to update a
and also have the list updating itself, in a clean way?
Of course I could simply do ls[0] = False
and be done. But in a large project, with many moving parts, I’d like to avoid non-descriptive bracket indexing.
I assume I could do some messy construct of an instantiated class, and then iterate over the attributes, but that sounds like messy business. Or is it?
Answers:
If you want to avoid indexing and have easy to read attributes then you could just use a class that has class attributes:
class Data:
a = True
and keep multiple references to it:
data = Data
data2 = Data # or similarly data2 = data
data.a = False
print(data2.a)
# False
Note that if you instantiate the class you’ll need to keep a reference to the instance rather than the class as the original class won’t be updated anymore:
data = Data()
data2 = data
data.a = 123
print(data2.a)
# 123
# original class remains unchanged
print(Data().a)
# True
From Python 3.7 you can use a dataclass, which makes instantiation with custom data simpler:
from dataclasses import dataclass
@dataclass
class Data:
a = True
data = Data(a=False)
data2 = data
print(data2.a)
# False
Finally, if you do care about variable states then there’s a good chance you’ll be working within a class anyway, in which case you could use a property:
class SomeClass:
def __init__(self):
self.a = False
self.b = True
@property
def ls(self):
return self.a, self.b
some_class = SomeClass()
some_class.a = True
print(some_class.ls)
# True, True
I suggest you this quite simple solution defining ls
as a function instead of a simple list. In this way, ls()
will always returns the updated values of a
and b
. The code is very close to your original code:
a = True
b = False
ls = lambda:[a,b]
a = False
print(ls()) # [False, False]
b = True
print(ls()) # [False, True]
In its essence, I do this:
a = True
b = False
ls = [a, b]
a = False
print(ls)
> [True, False]
And what happens is that whatever happens to a
is decoupled from the list after the first inclusion. Is there any way to update a
and also have the list updating itself, in a clean way?
Of course I could simply do ls[0] = False
and be done. But in a large project, with many moving parts, I’d like to avoid non-descriptive bracket indexing.
I assume I could do some messy construct of an instantiated class, and then iterate over the attributes, but that sounds like messy business. Or is it?
If you want to avoid indexing and have easy to read attributes then you could just use a class that has class attributes:
class Data:
a = True
and keep multiple references to it:
data = Data
data2 = Data # or similarly data2 = data
data.a = False
print(data2.a)
# False
Note that if you instantiate the class you’ll need to keep a reference to the instance rather than the class as the original class won’t be updated anymore:
data = Data()
data2 = data
data.a = 123
print(data2.a)
# 123
# original class remains unchanged
print(Data().a)
# True
From Python 3.7 you can use a dataclass, which makes instantiation with custom data simpler:
from dataclasses import dataclass
@dataclass
class Data:
a = True
data = Data(a=False)
data2 = data
print(data2.a)
# False
Finally, if you do care about variable states then there’s a good chance you’ll be working within a class anyway, in which case you could use a property:
class SomeClass:
def __init__(self):
self.a = False
self.b = True
@property
def ls(self):
return self.a, self.b
some_class = SomeClass()
some_class.a = True
print(some_class.ls)
# True, True
I suggest you this quite simple solution defining ls
as a function instead of a simple list. In this way, ls()
will always returns the updated values of a
and b
. The code is very close to your original code:
a = True
b = False
ls = lambda:[a,b]
a = False
print(ls()) # [False, False]
b = True
print(ls()) # [False, True]