| 178 | return len(self.dtype) |
| 179 | |
| 180 | def __getattribute__(self, attr): |
| 181 | try: |
| 182 | return object.__getattribute__(self, attr) |
| 183 | except AttributeError: |
| 184 | # attr must be a fieldname |
| 185 | pass |
| 186 | fielddict = np.ndarray.__getattribute__(self, 'dtype').fields |
| 187 | try: |
| 188 | res = fielddict[attr][:2] |
| 189 | except (TypeError, KeyError) as e: |
| 190 | raise AttributeError( |
| 191 | f'record array has no attribute {attr}') from e |
| 192 | # So far, so good |
| 193 | _localdict = np.ndarray.__getattribute__(self, '__dict__') |
| 194 | _data = np.ndarray.view(self, _localdict['_baseclass']) |
| 195 | obj = _data.getfield(*res) |
| 196 | if obj.dtype.names is not None: |
| 197 | raise NotImplementedError("MaskedRecords is currently limited to" |
| 198 | "simple records.") |
| 199 | # Get some special attributes |
| 200 | # Reset the object's mask |
| 201 | hasmasked = False |
| 202 | _mask = _localdict.get('_mask', None) |
| 203 | if _mask is not None: |
| 204 | try: |
| 205 | _mask = _mask[attr] |
| 206 | except IndexError: |
| 207 | # Couldn't find a mask: use the default (nomask) |
| 208 | pass |
| 209 | tp_len = len(_mask.dtype) |
| 210 | hasmasked = _mask.view((bool, ((tp_len,) if tp_len else ()))).any() |
| 211 | if (obj.shape or hasmasked): |
| 212 | obj = obj.view(ma.MaskedArray) |
| 213 | obj._baseclass = np.ndarray |
| 214 | obj._isfield = True |
| 215 | obj._mask = _mask |
| 216 | # Reset the field values |
| 217 | _fill_value = _localdict.get('_fill_value', None) |
| 218 | if _fill_value is not None: |
| 219 | try: |
| 220 | obj._fill_value = _fill_value[attr] |
| 221 | except ValueError: |
| 222 | obj._fill_value = None |
| 223 | else: |
| 224 | obj = obj.item() |
| 225 | return obj |
| 226 | |
| 227 | def __setattr__(self, attr, val): |
| 228 | """ |