0

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)
Chaban33
  • 1,362
  • 11
  • 38

2 Answers2

2

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)
ljmc
  • 4,830
  • 2
  • 7
  • 26
  • A problem with the first approach is that `test.my_data.append("x")` will silently fail to do anything. – Stuart Aug 10 '22 at 12:58
  • That’s true. I’ll update ASAP. – ljmc Aug 10 '22 at 13:02
  • 1
    Not saying I would change it, just wanted to highlight the limitation. It may be a good solution for some especially as it's simple to implement. – Stuart Aug 10 '22 at 13:03
1

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

nomans_
  • 68
  • 4