Custom array like implementation with components x, y, z I want to implement a custom vector-like in Python that stores its components in a list (or another container). And I want to access the components as x, y and z in order to get and set them. What is the best way to do it?

I implemented it like this:

import numpy as np

class Vector3d:
    components = ['x', 'y', 'z']

    def __init__(self):
        self._data = np.array([0.0, 0.0, 0.0])

    def __getattr__(self, key):
        if key in self.components:
            index = self.components.index(key)
            return self._data[index]
        else:
            return super().__getattr__(key)

    def __setattr__(self, key, value):
        if key in self.components:
            index = self.components.index(key)
            self._data[index] = value
        else:
            return super().__setattr__(key, value)

    def __repr__(self):
        return repr(self._data)

    def norm(self):
        return np.linalg.norm(self._data)

a = Vector3d()
a.x = 1.2
a.y = 2.3
a.z = 3.4
print(a.x, a.y, a.z)
print(a)
print(a.norm())


Here are the aspects that I dislike about it: 


First, I duplicated the code if key in self.components: index = self.components.index(key).
Second, searching for the index every time seems to be non-optimal towards the consuming time. I believe there's a better way to implement it. 


Please, suggest different approaches to me.

There may be many causes of doing it. For example, I may want to store the components as (ctypes.c_double * 3) array and to pass them to a DLL to gain performance of some calculations. Or to store them as numpy.array having the access to all numpy array methods. But I still want to keep the access to the components through x, y, z from the outside.
I suggest you to use a solution that relies on properties notion. This is simpler and more efficient to implement. Here is what you can do:

class CustomArrayLike:

    def __init__(self):
       self._x = None
       self._y = None
       self._z = None

    @property
    def x(self):
       return self._x

    @x.setter
    def x(self, value):
       self._x = value

    @property
    def y(self):
       return self._y

    @y.setter
    def y(self, value):
       self._y = value

    @property
    def z(self):
       return self._z

    @x.setter
    def z(self, value):
       self._z = value

    def __repr__(self):
       return repr([self._x, self._y, self._z])


if __name__ == '__main__':
   a = CustomArrayLike()
   a.x = 1.2
   a.y = 2.3
   a.z = 3.4
   print(a.x, a.y, a.z)
   print(a)