Использование [('x', 'float'), ('y', 'float')]
в качестве типа данных сообщает numpy для создания структурированного массива с полями с именами x
и y
.
Доступ к ним осуществляется с помощью скобок, как вы показали.
Теперь вы также добавили атрибуты (доступ к которым осуществляется с помощью obj.<name>
) для вашего класса.
Тем не менее, вы создали новые массивы для атрибутов.
Чтобы исправить обозначение атрибута, необходимо, чтобы атрибуты x
и y
указывали на поля массива по этим именам, а не на отдельные массивы.
Так что поменяй
obj.x = numpy.array(x, dtype='float')
obj.y = numpy.array(y, dtype='float')
до
obj.x = obj['x']
obj.y = obj['y']
edit это исправляет только второй контрольный пример в вопросе. Присвоение x
или y
по-прежнему назначает новый объект в качестве атрибута, а не обновление x
или y
.
Чтобы это исправить, необходимо изменить метод класса __setattr__
(см. здесь )
def __setattr__(self, attr, value):
if attr in ['x', 'y']:
getattr(self, attr)[:] = attr
else:
setattr(self, attr, value)
Однако у Numpy уже есть тип массива, позволяющий обращаться к полям в качестве атрибутов.
Вы можете использовать это так
obj = np.array(np.r_[x, y], dtype=[('x', 'float'), ('y', 'float')])
obj = obj.view(np.recarray)
Так что поздравляю! Вы фактически повторно внедрили массив записей (ну, np.recarray
не позволит получить доступ к именам полей, соответствующих атрибутам или функциям ndarray
. Значит, такие имена, как mean
или ndim
, отсутствуют, в то время как ваш код позволит это).
Это всегда хороший (и очень расстраивающий) признак, когда вы часами тратите на создание чего-то, что уже есть у numpy.