2

In python I have getters and setters, and calculate utilities. The getters return the property, the setters set the property and the calculate utilities are functions that calculate stuff with the arguments. E.g.

obj.property = calculate_property(arguments)

However, there are various ways to implement calculate_property, it could

  1. be a part of the class calculate_property(self) and return _property
  2. It could be an independent function which could be moved to a separate file
  3. It could be a static method

My problem with 1) is that the arguments to calculate_property can be obscured because they might be contained within the object itself, and it is not possible to use the function outside of the object. In both 2 and 3 the functional form of calculate is retained but the namespaces are different.

So I'm ruling out 1) for this reason.

IIf I go with 2) the advantage is that I can split all my utilities up into small files e.g. utilities_a.py, utilities_b.py and import them as modules.

If I go with 3) the functions remain in the same file making it overall longer, but the functions are encapsulated better.

Which is preferred between 2) and 3)? Or am I missing a different solution?

Cody Aldaz
  • 160
  • 7
  • 1
    `1` is not possible because you've already stated the data is rather buried; meanwhile I would pick `3` over `2` because it does seem very intimate to your class (it creates its properties) and would serve as helper. – Razzle Shazl Mar 08 '21 at 01:03
  • Here is an [example](https://stackoverflow.com/a/47562412/2359945) of achieving both `2` and `3`. Just remember to add `self` into the signature as is mentioned, and you can place your class methods and static methods in another file then import only as you need. – Razzle Shazl Mar 08 '21 at 01:07

1 Answers1

2

You can achieve both 2 and 3 with this example of adding a static method to your class that is defined in a separate file.

helper.py:

def square(self):
    self.x *= self.x

fitter.py:

class Fitter(object):
    def __init__(self, x: int):
        self.x = x
    from helper import square

if name == '__main__':
    f = Fitter(9)
    f.square()
    print(f.x)

Output:

81

Adapted from this answer which was doing this for a class method. Seems to work for static method, too.

Razzle Shazl
  • 1,287
  • 1
  • 8
  • 20
  • 1
    Wow, that's really cool! Importing inside the class definition adds it to the class namespace. This is what I liked about static methods and keeping the files separate. However, I agree with your comment above strategy 3 is probably the most clear despite the length of the files becoming long. – Cody Aldaz Mar 08 '21 at 04:45
  • @Cody I thought it was cool too :) If you found this answer useful, please consider accepting it. Thank you. – Razzle Shazl Mar 08 '21 at 04:47
  • 1
    @CodyAldaz I've already used imports in functions and maybe in classes. (E.g. pdb.set_trace()). Never realized that import set the object into that namespace. Good to know. Thanks. – Arpad Horvath -- Слава Україні Mar 10 '21 at 10:25