简体   繁体   中英

Python method calls in constructor and variable naming conventions inside a class

I try to process some data in Python and I defined a class for a sub-type of data. You can find a very simplified version of the class definition below.

class MyDataClass(object):
    def __init__(self, input1, input2, input3):
        """
        input1 and input2 are a 1D-array
        input3 is a 2D-array
        """
        self._x_value = None      # int
        self._y_value = None      # int
        self.data_array_1 = None  # 2D array
        self.data_array_2 = None  # 1D array

        self.set_data(input1, input2, input3)

    def set_data(self, input1, input2, input3):

        self._x_value, self._y_value = self.get_x_and_y_value(input1, input2)
        self.data_array_1 = self.get_data_array_1(input1)
        self.data_array_2 = self.get_data_array_2(input3)


    @staticmethod
    def get_x_and_y_value(input1, input2):
        # do some stuff
        return x_value, y_value

    def get_data_array_1(self, input1):
        # do some stuff
        return input1[self._x_value:self._y_value + 1]

    def get_data_array_2(self, input3):
        q = self.data_array_1 - input3[self._x_value:self._y_value + 1, :]
        return np.linalg.norm(q, axis=1)

I'm trying to follow the ' Zen of Python ' and thereby to write beautiful code. I'm quite sceptic, whether the class definition above is a good pratice or not. While I was thinking about alternatives I came up with the following questions, to which I would like to kindly get your opinions and suggestions.

  1. Does it make sense to define ''get'' and ''set'' methods?

    IMHO, as the resulting data will be used several times (in several plots and computation routines), it is more convenient to create and store them once. Hence, I calculate the data arrays once in the constructor.

    I do not deal with huge amount of data and therefore processing takes not more than a second, however I cannot estimate its potential implications on RAM if someone would use the same procedure for huge data.


  1. Should I put the function get_x_and_y_value() out of the class scope and convert static method to a function?

    As the method is only called inside the class definition, it is better to use it as a static method. If I should define it as a function, should I put all the lines relevant to this class inside a script and create a module of it?


  1. The argument naming of the function get_x_and_y_value() are the same as __init__ method. Should I change it?

    It would ease refactoring but could confuse others who read it.

In Python, you do not need getter and setter functions. Use properties instead. This is why you can access attributes directly in Python, unlike other languages like Java where you absolutely need to use getters and setters and to protect your attributes.

Consider the following example of a Circle class. Because we can use the @property decorator, we don't need getter and setter functions like other languages do. This is the Pythonic answer.

This should address all of your questions.

class Circle(object):
    def __init__(self, radius):
        self.radius = radius
        self.x = 0
        self.y = 0

    @property
    def diameter(self):
        return self.radius * 2

    @diameter.setter
    def diameter(self, value):
        self.radius = value / 2

    @property
    def xy(self):
        return (self.x, self.y)

    @xy.setter
    def xy(self, xy_pair):
        self.x, self.y = xy_pair


>>> c = Circle(radius=10)
>>> c.radius
10
>>> c.diameter
20
>>> c.diameter = 10
>>> c.radius
5.0
>>> c.xy
(0, 0)
>>> c.xy = (10, 20)
>>> c.x
10
>>> c.y
20

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM