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