pythonpython-dataclasses

How to make dataclass instance attribute non-public and an __init__ arg?


If I want an instance attribute to be:

Normally, I would do this:

class Foo:
    def __init__(self, bar: str):
        self._bar = bar

foo = Foo(bar="bar")  # foo.bar would raise an AttributeError

However, in dataclasses, I'm unsure how to do this.

from dataclasses import dataclass

@dataclass
class Foo:
    bar: str  # This leaves bar as a public instance attribute

What is the correct way to do this in dataclasses.dataclass?


Solution

  • If you want it to be an __init__() argument, just write your own which will prevent one from being automatically generated. Note that specifying init=False as shown below isn't really required since it wouldn't have happened anyway, but nevertheless seems like good way to draw attention to what's going on. For the same reason, specifying field(init=False) for the private _bar field is superfluous.

    from dataclasses import dataclass, field
    
    
    @dataclass(init=False)
    class Foo:
        def __init__(self, bar: str):
            self._bar = bar
    
        _bar: str = field(init=False)
    
    
    foo = Foo(bar="xyz")
    print(foo._bar)  # -> xyz
    print(foo.bar)  # -> AttributeError: 'Foo' object has no attribute 'bar'