Update the object with the given data object, and with any other key-value args. Returns a
    set containing all the property names that were changed.

def update(self, data_=None, **kwargs):
    """Update the object with the given data object, and with any other key-value args. Returns a
    set containing all the property names that were changed.
    """
    if data_ is None:
      data_ = dict()
    else:
      data_ = dict(data_)
    data_.update(**kwargs)
    changes = set()
    for attr_name in data_:
      if hasattr(self, attr_name):
        if getattr(self, attr_name) != data_[attr_name]:
          changes.add(attr_name)
          setattr(self, attr_name, data_[attr_name])
      else:
        if self.strict_attrs:
          raise Exception("Unknown attribute for {}: {}".format(self.__class__.__name__, attr_name))
    return changes