persephone
persephone copied to clipboard
Make the `Corpus.get*fns()` methods use the @property decorator
Makes for a simpler interface and since Corpus.prefixes
will not change after Corpus
construction, these can be considered properties that should be unchanging.
So you can replace function calls with their return value like this: https://github.com/JaggedVerge/PythonSnippets/blob/master/utils/lazy_property.py
I feel like there's a few downsides of this approach, but might be applicable here if the underlying object is immutable.
What are the pros and cons of this as compared to what I'm doing with num_feats at the moment? That is:
@property
def num_feats(self):
""" The number of features per time step in the corpus. """
if not self._num_feats:
filename = self.get_train_fns()[0][0]
feats = np.load(filename)
# pylint: disable=maybe-no-member
if len(feats.shape) == 3:
# Then there are multiple channels of multiple feats
self._num_feats = feats.shape[1] * feats.shape[2]
elif len(feats.shape) == 2:
# Otherwise it is just of shape time x feats
self._num_feats = feats.shape[1]
else:
raise ValueError(
"Feature matrix of shape %s unexpected" % str(feats.shape))
return self._num_feats
The main pro is that it removes the function call entirely. The main downside is that it introduces some code that's a bit harder to understand because it's actually not quite the same as a property due to some edge cases, specifically I'm not sure how this handles an exception thrown on the first usage and I'd need to analyze it to say for sure. And really that's the issue, it's more complex, so you really want to make sure the performance benefits are there for it (and sometimes after profiling this can be a big deal).
The underlying property has to be immutable otherwise replacing the attribute with the function call result will put the class in a potentially bad error state.
Okay, let's just stick with the standard property decorator for now.