Mutable named tuple with default value and conditional rounding support I have following code to create a mutable namedtuple. based my understand I can use dataclass to do it. is there a better way to do it or clean up the code?

@dataclass
class Price:
    """
    This describes how to map default price value for product
    """
    profit: float = 0.5
    cost: float = 0.1
    sale: float = 25.0

    def round(self, n: float):
        if n &lt; 1:
            return round(n, 2)
        elif n &lt; 100:
            n = round(n / 1)
        elif n &lt; 1000:
            n = round(n / 5) * 5
        elif n &lt; 10000:
            n = round(n / 50) * 50
        else:
            n = round(n / 500) * 500
        return n

    def update(self, **kwargs):
        rate = kwargs.get('rate', 1)
        for k, v in asdict(self).items():
            if k != 'sale':
                v = self.round(v * rate)
            v = kwargs.get(k) or v
            setattr(self, k, float(v))

#run test
p = Price()
p.update(rate=1) #p = Price(profit=0.5, cost=0.1, sale=25.0)

p = Price()
p.update(**{sale=450}, **dict(rate=0.9073)) #p = Price(profit=0.45, cost=0.1, sale=450.0)

p = Price()
p.update(**{sale=800}, **dict(rate=301.377)) #p = Price(profit=150.0, cost=0.1, sale=800.0)

p = Price()
p.update(rate=301.377) #p = Price(profit=150.0, cost=0.1, sale=7550.0)

p = Price(0.0, 0.5, 50.0)
p.update(rate=1) #p = Price(profit=0.0, cost=0.5, sale=50.0)

p = Price(0.0, 0.5, 50.0)
p.update(**{sale=600}, **dict(rate=0.9073)) #p = Price(profit=0.0, cost=0.5, sale=600.0)

p = Price(0.0, 0.5, 50.0)
p.update(**{sale=1200}, **dict(rate=301.377)) #p = Price(profit=0.0, cost=0.5, sale=1200.0)

p = Price(0.0, 0.5, 50.0)
p.update(rate=301.377) #p = Price(profit=0.0, cost=0.5, sale=15000.0)
In short:


dataclass is the right thing to use as a mutable named tuple. It's basically custom-built to be a great version of that idea.
Use decimal.Decimal for any financial numbers.
Don't re-implement round. There's a built-in version that behaves in nice, configurable ways with the Decimal object.
Not sure what the p.update(**{sale=600}, **dict(rate=0.9073)) is all about, just use p.update(sale=600, rate=0.9073) (except with Decimals)