Reputation: 9795
I want to implement 3D vector in Python that stores its components in a numpy array (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())
What I dislike in 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 me your approaches.
I'm searching for a solution for Python 3.
Upvotes: 0
Views: 740
Reputation: 399
Okay, the comment section seems constricting, so I'll move here...
Here is what I made out, ordered by priority:
if key in self.components
is linearly searching for the component x
(or others).Maybe this is something that can work:
import numpy as np
class Vector3d:
components = {'x':0, 'y':1, 'z':2}
def __init__(self):
self._data = [0.0, 0.0, 0.0]
def __getattr__(self, key):
return self._data[components[key]] ###!!!
def __setattr__(self, key, value):
self._data[components[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())
self._data[components[key]]
is something we got to live with! :DYou can add a try
and catch
to access data from super()
in case the return self._data[components[key]]
fails!
Upvotes: 3