Change list to immutable object
Question:
As you can see input data
and output my_data
is mutable objects, how can I make my_data
immutable and still have the possibility to iterate on it? (basically same behavior) use another dataclass?
from dataclasses import dataclass
data = {'demo1': "description for demo 1", "demo2": 'description for demo 2'}
@dataclass(frozen=True)
class SomeDataclass:
name: str
description: str
class ParserClass:
def __init__(self) -> None:
self.my_data = []
def parsing_method(self, demo_data) -> None:
for data, description in demo_data.items():
self.my_data.append(SomeDataclass(name=data, description=description))
test = ParserClass()
test.parsing_method(data)
for my_date in test.my_data:
print(my_date.name, my_date.description)
Answers:
If your parser is a class, you can turn any of its attributes into read only attributes with @property
:
class ParserClass:
def __init__(self) -> None:
self._my_data = []
@property
def my_data(self):
return self._my_data.copy() # copy to pass a new list, not the one in the parser
def parsing_method(self, demo_data) -> None:
for data, description in demo_data.items():
self._my_data.append(SomeDataclass(name=data, description=description))
NB. as list are mutable, we are using copy
to keep the private _my_data
read-only, the returned copy can be modified (e.g. inst.my_data.append(something)
), but that will not be reflected on the original private _my_data
.
Or with @match’s suggestion:
class ParserClass:
def __init__(self) -> None:
self._my_data = tuple()
def parsing_method(self, demo_data) -> None:
tmp_data = []
for data, description in demo_data.items():
tmp_data.append(SomeDataclass(name=data, description=description))
self.my_data = tuple(tmp_data)
I suppose you can simply convert them to tuples by using tuple() function. Tuple is immutable and iterable.
Edit: Someone else suggested it in a reply to your question when I was typing this. But I’ll just leave it here
As you can see input data
and output my_data
is mutable objects, how can I make my_data
immutable and still have the possibility to iterate on it? (basically same behavior) use another dataclass?
from dataclasses import dataclass
data = {'demo1': "description for demo 1", "demo2": 'description for demo 2'}
@dataclass(frozen=True)
class SomeDataclass:
name: str
description: str
class ParserClass:
def __init__(self) -> None:
self.my_data = []
def parsing_method(self, demo_data) -> None:
for data, description in demo_data.items():
self.my_data.append(SomeDataclass(name=data, description=description))
test = ParserClass()
test.parsing_method(data)
for my_date in test.my_data:
print(my_date.name, my_date.description)
If your parser is a class, you can turn any of its attributes into read only attributes with @property
:
class ParserClass:
def __init__(self) -> None:
self._my_data = []
@property
def my_data(self):
return self._my_data.copy() # copy to pass a new list, not the one in the parser
def parsing_method(self, demo_data) -> None:
for data, description in demo_data.items():
self._my_data.append(SomeDataclass(name=data, description=description))
NB. as list are mutable, we are using copy
to keep the private _my_data
read-only, the returned copy can be modified (e.g. inst.my_data.append(something)
), but that will not be reflected on the original private _my_data
.
Or with @match’s suggestion:
class ParserClass:
def __init__(self) -> None:
self._my_data = tuple()
def parsing_method(self, demo_data) -> None:
tmp_data = []
for data, description in demo_data.items():
tmp_data.append(SomeDataclass(name=data, description=description))
self.my_data = tuple(tmp_data)
I suppose you can simply convert them to tuples by using tuple() function. Tuple is immutable and iterable.
Edit: Someone else suggested it in a reply to your question when I was typing this. But I’ll just leave it here