Question: I have a Device class like so, that I pass data from a websocket to. The data from the websocket isn't always the same, so what I want to do is only update the value of each item in the class, if it is not None.

As an example, the `message_data` might be the below on the first message

```json
{
  "ssdp": "foo",
  "ip": "bar"
}

```

and then the following on the second:

```json
{
  "ssdp": "foo",
}

```

My code is below:

**Script**

```py
                if self._device is None:
                    self._device = Device(message_data)

                device = self._device.update_from_dict(message_data)

```

**Class**

```py
@dataclass
class Info:
    ssdp: str
    ip: str

    @staticmethod
    def from_dict(data):
        return Info(
            ssdp=data.get('SSDP'),
            ip=data.get('ip'),
        )

class Device:
    def __init__(self, data):
        self.info = None
        self.update_from_dict(data)

    def update_from_dict(self, data):
        self.info = Info.from_dict(data)
        return self

```

Unfortunately at the moment, this is returning

```
{'info': Info(ssdp='foo', ip='bar')}

```

and then

```
{'info': Info(ssdp='foo', ip=None)}

```

Answer: 
You never show exactly how you use your `class Device`, so I'm going to have to guess:

You create a new `Device` from data, and later you get new data and want to do an update.

This constitutes two completely different operations, and `Device` already has these two operations, but `Info` does not.

Here is my code with two methods for `Info`:

```py
from dataclasses import dataclass

@dataclass
class Info:
    ssdp: str
    ip: str

    @staticmethod
    def from_dict(data):
        return Info(
            ssdp=data.get('ssdp'),
            ip=data.get('ip'),
        )
    def update_from_dict(self, data):
        self.ssdp = data.get('ssdp', self.ssdp)
        self.ip = data.get('ip', self.ip)

class Device:
    def __init__(self, data):
        self.info = Info.from_dict(data)

    def update_from_dict(self, data):
        self.info.update_from_dict(data)
        return self

    def __repr__(self):
        return str(self.info)

d1 = {
  "ssdp": "foo",
  "ip": "bar"
}

d2 = {
  "ssdp": "test",
}

dev = Device(d1)
print(dev)
dev.update_from_dict(d2)
print(dev)

```

Output:

```
Info(ssdp='foo', ip='bar')
Info(ssdp='test', ip='bar')

```
Try with these redefined new classes:

```
from dataclasses import dataclass, fields, replace
from operator import attrgetter

@dataclass
class Info:
    ssdp: str = None
    ip: str = None

class Device:
    def __init__(self, data):
        self.info = Info()
        self.update_from_dict(data)

    def update_from_dict(self, data):
        keys = set(map(attrgetter('name'), fields(self.info)))
        data = {k: v for k, v in data.items() if k in keys}
        self.info = replace(self.info, **data)
        return self

```

This solution is using the [`replace`](https://docs.python.org/3/library/dataclasses.html#dataclasses.replace) function, which basically creates a new object of the same type as the input object, replacing fields with values from changes.