Skip to content
Advertisement

Python: Use the “value” of a class instance as the value of a specified class instance attribute

I am relatively new to Python and have a question relating to accessing class instance attributes.

Consider the example below

import numpy as np

class TwoDimensionalArray:
    def __init__(self, input_array):
        self.dimension_one_size = input_array.shape[0]
        self.dimension_two_size = input_array.shape[1]
        self.value = my_array

# Create an instance of the class TwoDimensionalArray.
numpy_array = np.array([[1, 2, 3], [4, 5, 6]])
example_two_dimensional_array = TwoDimensionalArray(numpy_array)

My actual code is a bit more complex than this example; the motivation for requiring this functionality is that I do not want to write numpy_array.shape[0] or numpy_array.shape[1] throughout my code base, but rather the dimensions must have names that are suitable for the business logic at hand.

Is it at all possible to modify the class TwoDimensionalArray in some way such that you get the input array without having to write a_different_array = example_two_dimensional_array.value (i.e. . to access the attribute value) but rather use the simplification a_different_array = example_two_dimensional_array i.e. a_different_array will then be equal to np.array([[1, 2, 3], [4, 5, 6]]) i.e. type(a_different_array) = type(numpy_array) = numpy.ndarray as opposed to type(a_different_array) = TwoDimensionalArray?

Advertisement

Answer

Found the solution here: https://numpy.org/doc/stable/user/basics.subclassing.html#simple-example-adding-an-extra-attribute-to-ndarray.

It seems the correct way to implement this is as follows

class TwoDimensionalArray(np.ndarray):
    def __new__(cls, input_array):
        obj = np.asarray(input_array).view(cls)
        obj.dimension_one_size = input_array.shape[0]
        obj.dimension_two_size = input_array.shape[1]
        return obj

    def __array_finalize__(self, obj):
        if obj is None: return
        self.dimension_one_size = getattr(obj, 'dimension_one_size', None)
        self.dimension_two_size = getattr(obj, 'dimension_two_size', None)        
        
numpy_array = np.array([[1, 2, 3], [4, 5, 6]])
example_two_dimensional_array = TwoDimensionalArray(numpy_array)

We now have two additional attributes added to np.ndarray: example_two_dimensional_array.dimension_one_size = 2 and example_two_dimensional_array.dimension_two_size = 3.

User contributions licensed under: CC BY-SA
10 People found this is helpful
Advertisement