code: def add_attribute(self, attr, val, as_property=False):
      if not as_property:
          self._data_dict[attr] = val
      else:
          val_type = type(val).__name__
          if "attributes" not in self._data_dict:
              self._data_dict["attributes"] = {}
          if val_type not in self._data_dict["attributes"]:
              self._data_dict["attributes"][val_type] = []
  
          attr_dict = {"name": attr, "val": val}
          self._data_dict["attributes"][val_type].append(attr_dict)
  
imports: from collections import defaultdict
  import os
  import eta.core.serial
  import fiftyone.core.odm.dataset
label_desc: Use image node_id 3 for calling the OpenLABELObjectData obj's underlying member method code with example usage: obj.add_attribute(attr, val, as_property) without return types