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.
components
array for different items, or are all of them just going to havex y z
? \$\endgroup\$