title: Validating input when mutating a dataclass
body: <p>In Python 3.7 there are these new "dataclass" containers that are basically like mutable namedtuples. Suppose I make a dataclass that is meant to represent a person. I can add input validation via the <code>__post_init__()</code> function like this:</p>
  
  <pre><code>@dataclass
  class Person:
      name: str
      age: float
  
      def __post_init__(self):
          if type(self.name) is not str:
              raise TypeError("Field 'name' must be of type 'str'.")
          self.age = float(self.age)
          if self.age &lt; 0:
              raise ValueError("Field 'age' cannot be negative.")
  </code></pre>
  
  <p>This will let good inputs through:</p>
  
  <pre><code>someone = Person(name="John Doe", age=30)
  print(someone)
  
  Person(name='John Doe', age=30.0)
  </code></pre>
  
  <p>While all of these bad inputs will throw an error:</p>
  
  <pre><code>someone = Person(name=["John Doe"], age=30)
  someone = Person(name="John Doe", age="thirty")
  someone = Person(name="John Doe", age=-30)
  </code></pre>
  
  <p>However, since dataclasses are mutable, I can do this:</p>
  
  <pre><code>someone = Person(name="John Doe", age=30)
  someone.age = -30
  print(someone)
  
  Person(name='John Doe', age=-30)
  </code></pre>
  
  <p>Thus bypassing the input validation.</p>
  
  <p>So, what is the best way to make sure that the fields of a dataclass aren't mutated to something bad, <strong>after</strong> initialization? </p>